ActivityManagerService.java revision 62515beee67307d8859beec521b7baedfa54b2b5
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.content.DialogInterface.OnClickListener;
40import android.content.res.Resources;
41import android.graphics.BitmapFactory;
42import android.graphics.Rect;
43import android.os.BatteryStats;
44import android.os.PersistableBundle;
45import android.service.voice.IVoiceInteractionSession;
46import android.util.ArrayMap;
47
48import com.android.internal.R;
49import com.android.internal.annotations.GuardedBy;
50import com.android.internal.app.IAppOpsService;
51import com.android.internal.app.IVoiceInteractor;
52import com.android.internal.app.ProcessMap;
53import com.android.internal.app.ProcessStats;
54import com.android.internal.content.PackageMonitor;
55import com.android.internal.os.BackgroundThread;
56import com.android.internal.os.BatteryStatsImpl;
57import com.android.internal.os.ProcessCpuTracker;
58import com.android.internal.os.TransferPipe;
59import com.android.internal.os.Zygote;
60import com.android.internal.util.FastPrintWriter;
61import com.android.internal.util.FastXmlSerializer;
62import com.android.internal.util.MemInfoReader;
63import com.android.internal.util.Preconditions;
64import com.android.server.AppOpsService;
65import com.android.server.AttributeCache;
66import com.android.server.IntentResolver;
67import com.android.server.LocalServices;
68import com.android.server.ServiceThread;
69import com.android.server.SystemService;
70import com.android.server.SystemServiceManager;
71import com.android.server.Watchdog;
72import com.android.server.am.ActivityStack.ActivityState;
73import com.android.server.firewall.IntentFirewall;
74import com.android.server.pm.UserManagerService;
75import com.android.server.wm.AppTransition;
76import com.android.server.wm.WindowManagerService;
77import com.google.android.collect.Lists;
78import com.google.android.collect.Maps;
79
80import libcore.io.IoUtils;
81
82import org.xmlpull.v1.XmlPullParser;
83import org.xmlpull.v1.XmlPullParserException;
84import org.xmlpull.v1.XmlSerializer;
85
86import android.app.Activity;
87import android.app.ActivityManager;
88import android.app.ActivityManager.RunningTaskInfo;
89import android.app.ActivityManager.StackInfo;
90import android.app.ActivityManagerInternal;
91import android.app.ActivityManagerNative;
92import android.app.ActivityOptions;
93import android.app.ActivityThread;
94import android.app.AlertDialog;
95import android.app.AppGlobals;
96import android.app.ApplicationErrorReport;
97import android.app.Dialog;
98import android.app.IActivityController;
99import android.app.IApplicationThread;
100import android.app.IInstrumentationWatcher;
101import android.app.INotificationManager;
102import android.app.IProcessObserver;
103import android.app.IServiceConnection;
104import android.app.IStopUserCallback;
105import android.app.IUiAutomationConnection;
106import android.app.IUserSwitchObserver;
107import android.app.Instrumentation;
108import android.app.Notification;
109import android.app.NotificationManager;
110import android.app.PendingIntent;
111import android.app.backup.IBackupManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.ParceledListSlice;
136import android.content.pm.UserInfo;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PathPermission;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.res.CompatibilityInfo;
143import android.content.res.Configuration;
144import android.graphics.Bitmap;
145import android.net.Proxy;
146import android.net.ProxyInfo;
147import android.net.Uri;
148import android.os.Binder;
149import android.os.Build;
150import android.os.Bundle;
151import android.os.Debug;
152import android.os.DropBoxManager;
153import android.os.Environment;
154import android.os.FactoryTest;
155import android.os.FileObserver;
156import android.os.FileUtils;
157import android.os.Handler;
158import android.os.IBinder;
159import android.os.IPermissionController;
160import android.os.IRemoteCallback;
161import android.os.IUserManager;
162import android.os.Looper;
163import android.os.Message;
164import android.os.Parcel;
165import android.os.ParcelFileDescriptor;
166import android.os.Process;
167import android.os.RemoteCallbackList;
168import android.os.RemoteException;
169import android.os.SELinux;
170import android.os.ServiceManager;
171import android.os.StrictMode;
172import android.os.SystemClock;
173import android.os.SystemProperties;
174import android.os.UpdateLock;
175import android.os.UserHandle;
176import android.provider.Settings;
177import android.text.Spannable;
178import android.text.SpannableString;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.text.style.DynamicDrawableSpan;
182import android.text.style.ImageSpan;
183import android.util.AtomicFile;
184import android.util.EventLog;
185import android.util.Log;
186import android.util.Pair;
187import android.util.PrintWriterPrinter;
188import android.util.Slog;
189import android.util.SparseArray;
190import android.util.TimeUtils;
191import android.util.Xml;
192import android.view.Gravity;
193import android.view.LayoutInflater;
194import android.view.View;
195import android.view.WindowManager;
196import android.widget.TextView;
197
198import java.io.BufferedInputStream;
199import java.io.BufferedOutputStream;
200import java.io.DataInputStream;
201import java.io.DataOutputStream;
202import java.io.File;
203import java.io.FileDescriptor;
204import java.io.FileInputStream;
205import java.io.FileNotFoundException;
206import java.io.FileOutputStream;
207import java.io.IOException;
208import java.io.InputStreamReader;
209import java.io.PrintWriter;
210import java.io.StringWriter;
211import java.lang.ref.WeakReference;
212import java.util.ArrayList;
213import java.util.Arrays;
214import java.util.Collections;
215import java.util.Comparator;
216import java.util.HashMap;
217import java.util.HashSet;
218import java.util.Iterator;
219import java.util.List;
220import java.util.Locale;
221import java.util.Map;
222import java.util.Set;
223import java.util.concurrent.atomic.AtomicBoolean;
224import java.util.concurrent.atomic.AtomicLong;
225
226public final class ActivityManagerService extends ActivityManagerNative
227        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
228    private static final String USER_DATA_DIR = "/data/user/";
229    static final String TAG = "ActivityManager";
230    static final String TAG_MU = "ActivityManagerServiceMU";
231    static final boolean DEBUG = false;
232    static final boolean localLOGV = DEBUG;
233    static final boolean DEBUG_BACKUP = localLOGV || false;
234    static final boolean DEBUG_BROADCAST = localLOGV || false;
235    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
236    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_CLEANUP = localLOGV || false;
238    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
239    static final boolean DEBUG_FOCUS = false;
240    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
241    static final boolean DEBUG_MU = localLOGV || false;
242    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
243    static final boolean DEBUG_LRU = localLOGV || false;
244    static final boolean DEBUG_PAUSE = localLOGV || false;
245    static final boolean DEBUG_POWER = localLOGV || false;
246    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
247    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
248    static final boolean DEBUG_PROCESSES = localLOGV || false;
249    static final boolean DEBUG_PROVIDER = localLOGV || false;
250    static final boolean DEBUG_RESULTS = localLOGV || false;
251    static final boolean DEBUG_SERVICE = localLOGV || false;
252    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
253    static final boolean DEBUG_STACK = localLOGV || false;
254    static final boolean DEBUG_SWITCH = localLOGV || false;
255    static final boolean DEBUG_TASKS = localLOGV || false;
256    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
257    static final boolean DEBUG_TRANSITION = localLOGV || false;
258    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
259    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
260    static final boolean DEBUG_VISBILITY = localLOGV || false;
261    static final boolean DEBUG_PSS = localLOGV || false;
262    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
263    static final boolean VALIDATE_TOKENS = false;
264    static final boolean SHOW_ACTIVITY_START_TIME = true;
265
266    // Control over CPU and battery monitoring.
267    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
268    static final boolean MONITOR_CPU_USAGE = true;
269    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
270    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
271    static final boolean MONITOR_THREAD_CPU_USAGE = false;
272
273    // The flags that are set for all calls we make to the package manager.
274    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
275
276    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
277
278    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
279
280    // Maximum number of recent tasks that we can remember.
281    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200;
282
283    // Amount of time after a call to stopAppSwitches() during which we will
284    // prevent further untrusted switches from happening.
285    static final long APP_SWITCH_DELAY_TIME = 5*1000;
286
287    // How long we wait for a launched process to attach to the activity manager
288    // before we decide it's never going to come up for real.
289    static final int PROC_START_TIMEOUT = 10*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real, when the process was
293    // started with a wrapper for instrumentation (such as Valgrind) because it
294    // could take much longer than usual.
295    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
296
297    // How long to wait after going idle before forcing apps to GC.
298    static final int GC_TIMEOUT = 5*1000;
299
300    // The minimum amount of time between successive GC requests for a process.
301    static final int GC_MIN_INTERVAL = 60*1000;
302
303    // The minimum amount of time between successive PSS requests for a process.
304    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
305
306    // The minimum amount of time between successive PSS requests for a process
307    // when the request is due to the memory state being lowered.
308    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
309
310    // The rate at which we check for apps using excessive power -- 15 mins.
311    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
312
313    // The minimum sample duration we will allow before deciding we have
314    // enough data on wake locks to start killing things.
315    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on CPU usage to start killing things.
319    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // How long we allow a receiver to run before giving up on it.
322    static final int BROADCAST_FG_TIMEOUT = 10*1000;
323    static final int BROADCAST_BG_TIMEOUT = 60*1000;
324
325    // How long we wait until we timeout on key dispatching.
326    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
327
328    // How long we wait until we timeout on key dispatching during instrumentation.
329    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
330
331    // Amount of time we wait for observers to handle a user switch before
332    // giving up on them and unfreezing the screen.
333    static final int USER_SWITCH_TIMEOUT = 2*1000;
334
335    // Maximum number of users we allow to be running at a time.
336    static final int MAX_RUNNING_USERS = 3;
337
338    // How long to wait in getAssistContextExtras for the activity and foreground services
339    // to respond with the result.
340    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
341
342    // Maximum number of persisted Uri grants a package is allowed
343    static final int MAX_PERSISTED_URI_GRANTS = 128;
344
345    static final int MY_PID = Process.myPid();
346
347    static final String[] EMPTY_STRING_ARRAY = new String[0];
348
349    // How many bytes to write into the dropbox log before truncating
350    static final int DROPBOX_MAX_SIZE = 256 * 1024;
351
352    /** All system services */
353    SystemServiceManager mSystemServiceManager;
354
355    /** Run all ActivityStacks through this */
356    ActivityStackSupervisor mStackSupervisor;
357
358    public IntentFirewall mIntentFirewall;
359
360    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
361    // default actuion automatically.  Important for devices without direct input
362    // devices.
363    private boolean mShowDialogs = true;
364
365    /**
366     * Description of a request to start a new activity, which has been held
367     * due to app switches being disabled.
368     */
369    static class PendingActivityLaunch {
370        final ActivityRecord r;
371        final ActivityRecord sourceRecord;
372        final int startFlags;
373        final ActivityStack stack;
374
375        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
376                int _startFlags, ActivityStack _stack) {
377            r = _r;
378            sourceRecord = _sourceRecord;
379            startFlags = _startFlags;
380            stack = _stack;
381        }
382    }
383
384    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
385            = new ArrayList<PendingActivityLaunch>();
386
387    BroadcastQueue mFgBroadcastQueue;
388    BroadcastQueue mBgBroadcastQueue;
389    // Convenient for easy iteration over the queues. Foreground is first
390    // so that dispatch of foreground broadcasts gets precedence.
391    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
392
393    BroadcastQueue broadcastQueueForIntent(Intent intent) {
394        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
395        if (DEBUG_BACKGROUND_BROADCAST) {
396            Slog.i(TAG, "Broadcast intent " + intent + " on "
397                    + (isFg ? "foreground" : "background")
398                    + " queue");
399        }
400        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
401    }
402
403    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
404        for (BroadcastQueue queue : mBroadcastQueues) {
405            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
406            if (r != null) {
407                return r;
408            }
409        }
410        return null;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    ArrayList<TaskRecord> mRecentTasks;
422
423    public class PendingAssistExtras extends Binder implements Runnable {
424        public final ActivityRecord activity;
425        public boolean haveResult = false;
426        public Bundle result = null;
427        public PendingAssistExtras(ActivityRecord _activity) {
428            activity = _activity;
429        }
430        @Override
431        public void run() {
432            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
433            synchronized (this) {
434                haveResult = true;
435                notifyAll();
436            }
437        }
438    }
439
440    final ArrayList<PendingAssistExtras> mPendingAssistExtras
441            = new ArrayList<PendingAssistExtras>();
442
443    /**
444     * Process management.
445     */
446    final ProcessList mProcessList = new ProcessList();
447
448    /**
449     * All of the applications we currently have running organized by name.
450     * The keys are strings of the application package name (as
451     * returned by the package manager), and the keys are ApplicationRecord
452     * objects.
453     */
454    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
455
456    /**
457     * Tracking long-term execution of processes to look for abuse and other
458     * bad app behavior.
459     */
460    final ProcessStatsService mProcessStats;
461
462    /**
463     * The currently running isolated processes.
464     */
465    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
466
467    /**
468     * Counter for assigning isolated process uids, to avoid frequently reusing the
469     * same ones.
470     */
471    int mNextIsolatedProcessUid = 0;
472
473    /**
474     * The currently running heavy-weight process, if any.
475     */
476    ProcessRecord mHeavyWeightProcess = null;
477
478    /**
479     * The last time that various processes have crashed.
480     */
481    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
482
483    /**
484     * Information about a process that is currently marked as bad.
485     */
486    static final class BadProcessInfo {
487        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
488            this.time = time;
489            this.shortMsg = shortMsg;
490            this.longMsg = longMsg;
491            this.stack = stack;
492        }
493
494        final long time;
495        final String shortMsg;
496        final String longMsg;
497        final String stack;
498    }
499
500    /**
501     * Set of applications that we consider to be bad, and will reject
502     * incoming broadcasts from (which the user has no control over).
503     * Processes are added to this set when they have crashed twice within
504     * a minimum amount of time; they are removed from it when they are
505     * later restarted (hopefully due to some user action).  The value is the
506     * time it was added to the list.
507     */
508    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
509
510    /**
511     * All of the processes we currently have running organized by pid.
512     * The keys are the pid running the application.
513     *
514     * <p>NOTE: This object is protected by its own lock, NOT the global
515     * activity manager lock!
516     */
517    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
518
519    /**
520     * All of the processes that have been forced to be foreground.  The key
521     * is the pid of the caller who requested it (we hold a death
522     * link on it).
523     */
524    abstract class ForegroundToken implements IBinder.DeathRecipient {
525        int pid;
526        IBinder token;
527    }
528    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
529
530    /**
531     * List of records for processes that someone had tried to start before the
532     * system was ready.  We don't start them at that point, but ensure they
533     * are started by the time booting is complete.
534     */
535    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
536
537    /**
538     * List of persistent applications that are in the process
539     * of being started.
540     */
541    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
542
543    /**
544     * Processes that are being forcibly torn down.
545     */
546    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
547
548    /**
549     * List of running applications, sorted by recent usage.
550     * The first entry in the list is the least recently used.
551     */
552    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
553
554    /**
555     * Where in mLruProcesses that the processes hosting activities start.
556     */
557    int mLruProcessActivityStart = 0;
558
559    /**
560     * Where in mLruProcesses that the processes hosting services start.
561     * This is after (lower index) than mLruProcessesActivityStart.
562     */
563    int mLruProcessServiceStart = 0;
564
565    /**
566     * List of processes that should gc as soon as things are idle.
567     */
568    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
569
570    /**
571     * Processes we want to collect PSS data from.
572     */
573    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Last time we requested PSS data of all processes.
577     */
578    long mLastFullPssTime = SystemClock.uptimeMillis();
579
580    /**
581     * This is the process holding what we currently consider to be
582     * the "home" activity.
583     */
584    ProcessRecord mHomeProcess;
585
586    /**
587     * This is the process holding the activity the user last visited that
588     * is in a different process from the one they are currently in.
589     */
590    ProcessRecord mPreviousProcess;
591
592    /**
593     * The time at which the previous process was last visible.
594     */
595    long mPreviousProcessVisibleTime;
596
597    /**
598     * Which uses have been started, so are allowed to run code.
599     */
600    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
601
602    /**
603     * LRU list of history of current users.  Most recently current is at the end.
604     */
605    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
606
607    /**
608     * Constant array of the users that are currently started.
609     */
610    int[] mStartedUserArray = new int[] { 0 };
611
612    /**
613     * Registered observers of the user switching mechanics.
614     */
615    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
616            = new RemoteCallbackList<IUserSwitchObserver>();
617
618    /**
619     * Currently active user switch.
620     */
621    Object mCurUserSwitchCallback;
622
623    /**
624     * Packages that the user has asked to have run in screen size
625     * compatibility mode instead of filling the screen.
626     */
627    final CompatModePackages mCompatModePackages;
628
629    /**
630     * Set of IntentSenderRecord objects that are currently active.
631     */
632    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
633            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
634
635    /**
636     * Fingerprints (hashCode()) of stack traces that we've
637     * already logged DropBox entries for.  Guarded by itself.  If
638     * something (rogue user app) forces this over
639     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
640     */
641    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
642    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
643
644    /**
645     * Strict Mode background batched logging state.
646     *
647     * The string buffer is guarded by itself, and its lock is also
648     * used to determine if another batched write is already
649     * in-flight.
650     */
651    private final StringBuilder mStrictModeBuffer = new StringBuilder();
652
653    /**
654     * Keeps track of all IIntentReceivers that have been registered for
655     * broadcasts.  Hash keys are the receiver IBinder, hash value is
656     * a ReceiverList.
657     */
658    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
659            new HashMap<IBinder, ReceiverList>();
660
661    /**
662     * Resolver for broadcast intents to registered receivers.
663     * Holds BroadcastFilter (subclass of IntentFilter).
664     */
665    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
666            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
667        @Override
668        protected boolean allowFilterResult(
669                BroadcastFilter filter, List<BroadcastFilter> dest) {
670            IBinder target = filter.receiverList.receiver.asBinder();
671            for (int i=dest.size()-1; i>=0; i--) {
672                if (dest.get(i).receiverList.receiver.asBinder() == target) {
673                    return false;
674                }
675            }
676            return true;
677        }
678
679        @Override
680        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
681            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
682                    || userId == filter.owningUserId) {
683                return super.newResult(filter, match, userId);
684            }
685            return null;
686        }
687
688        @Override
689        protected BroadcastFilter[] newArray(int size) {
690            return new BroadcastFilter[size];
691        }
692
693        @Override
694        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
695            return packageName.equals(filter.packageName);
696        }
697    };
698
699    /**
700     * State of all active sticky broadcasts per user.  Keys are the action of the
701     * sticky Intent, values are an ArrayList of all broadcasted intents with
702     * that action (which should usually be one).  The SparseArray is keyed
703     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
704     * for stickies that are sent to all users.
705     */
706    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
707            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
708
709    final ActiveServices mServices;
710
711    /**
712     * Backup/restore process management
713     */
714    String mBackupAppName = null;
715    BackupRecord mBackupTarget = null;
716
717    final ProviderMap mProviderMap;
718
719    /**
720     * List of content providers who have clients waiting for them.  The
721     * application is currently being launched and the provider will be
722     * removed from this list once it is published.
723     */
724    final ArrayList<ContentProviderRecord> mLaunchingProviders
725            = new ArrayList<ContentProviderRecord>();
726
727    /**
728     * File storing persisted {@link #mGrantedUriPermissions}.
729     */
730    private final AtomicFile mGrantFile;
731
732    /** XML constants used in {@link #mGrantFile} */
733    private static final String TAG_URI_GRANTS = "uri-grants";
734    private static final String TAG_URI_GRANT = "uri-grant";
735    private static final String ATTR_USER_HANDLE = "userHandle";
736    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
737    private static final String ATTR_TARGET_USER_ID = "targetUserId";
738    private static final String ATTR_SOURCE_PKG = "sourcePkg";
739    private static final String ATTR_TARGET_PKG = "targetPkg";
740    private static final String ATTR_URI = "uri";
741    private static final String ATTR_MODE_FLAGS = "modeFlags";
742    private static final String ATTR_CREATED_TIME = "createdTime";
743    private static final String ATTR_PREFIX = "prefix";
744
745    /**
746     * Global set of specific {@link Uri} permissions that have been granted.
747     * This optimized lookup structure maps from {@link UriPermission#targetUid}
748     * to {@link UriPermission#uri} to {@link UriPermission}.
749     */
750    @GuardedBy("this")
751    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
752            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
753
754    public static class GrantUri {
755        public final int sourceUserId;
756        public final Uri uri;
757        public boolean prefix;
758
759        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
760            this.sourceUserId = sourceUserId;
761            this.uri = uri;
762            this.prefix = prefix;
763        }
764
765        @Override
766        public int hashCode() {
767            return toString().hashCode();
768        }
769
770        @Override
771        public boolean equals(Object o) {
772            if (o instanceof GrantUri) {
773                GrantUri other = (GrantUri) o;
774                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
775                        && prefix == other.prefix;
776            }
777            return false;
778        }
779
780        @Override
781        public String toString() {
782            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
783            if (prefix) result += " [prefix]";
784            return result;
785        }
786
787        public String toSafeString() {
788            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
789            if (prefix) result += " [prefix]";
790            return result;
791        }
792
793        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
794            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
795                    ContentProvider.getUriWithoutUserId(uri), false);
796        }
797    }
798
799    CoreSettingsObserver mCoreSettingsObserver;
800
801    /**
802     * Thread-local storage used to carry caller permissions over through
803     * indirect content-provider access.
804     */
805    private class Identity {
806        public int pid;
807        public int uid;
808
809        Identity(int _pid, int _uid) {
810            pid = _pid;
811            uid = _uid;
812        }
813    }
814
815    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
816
817    /**
818     * All information we have collected about the runtime performance of
819     * any user id that can impact battery performance.
820     */
821    final BatteryStatsService mBatteryStatsService;
822
823    /**
824     * Information about component usage
825     */
826    final UsageStatsService mUsageStatsService;
827
828    /**
829     * Information about and control over application operations
830     */
831    final AppOpsService mAppOpsService;
832
833    /**
834     * Save recent tasks information across reboots.
835     */
836    final TaskPersister mTaskPersister;
837
838    /**
839     * Current configuration information.  HistoryRecord objects are given
840     * a reference to this object to indicate which configuration they are
841     * currently running in, so this object must be kept immutable.
842     */
843    Configuration mConfiguration = new Configuration();
844
845    /**
846     * Current sequencing integer of the configuration, for skipping old
847     * configurations.
848     */
849    int mConfigurationSeq = 0;
850
851    /**
852     * Hardware-reported OpenGLES version.
853     */
854    final int GL_ES_VERSION;
855
856    /**
857     * List of initialization arguments to pass to all processes when binding applications to them.
858     * For example, references to the commonly used services.
859     */
860    HashMap<String, IBinder> mAppBindArgs;
861
862    /**
863     * Temporary to avoid allocations.  Protected by main lock.
864     */
865    final StringBuilder mStringBuilder = new StringBuilder(256);
866
867    /**
868     * Used to control how we initialize the service.
869     */
870    ComponentName mTopComponent;
871    String mTopAction = Intent.ACTION_MAIN;
872    String mTopData;
873    boolean mProcessesReady = false;
874    boolean mSystemReady = false;
875    boolean mBooting = false;
876    boolean mWaitingUpdate = false;
877    boolean mDidUpdate = false;
878    boolean mOnBattery = false;
879    boolean mLaunchWarningShown = false;
880
881    Context mContext;
882
883    int mFactoryTest;
884
885    boolean mCheckedForSetup;
886
887    /**
888     * The time at which we will allow normal application switches again,
889     * after a call to {@link #stopAppSwitches()}.
890     */
891    long mAppSwitchesAllowedTime;
892
893    /**
894     * This is set to true after the first switch after mAppSwitchesAllowedTime
895     * is set; any switches after that will clear the time.
896     */
897    boolean mDidAppSwitch;
898
899    /**
900     * Last time (in realtime) at which we checked for power usage.
901     */
902    long mLastPowerCheckRealtime;
903
904    /**
905     * Last time (in uptime) at which we checked for power usage.
906     */
907    long mLastPowerCheckUptime;
908
909    /**
910     * Set while we are wanting to sleep, to prevent any
911     * activities from being started/resumed.
912     */
913    private boolean mSleeping = false;
914
915    /**
916     * Set while we are running a voice interaction.  This overrides
917     * sleeping while it is active.
918     */
919    private boolean mRunningVoice = false;
920
921    /**
922     * State of external calls telling us if the device is asleep.
923     */
924    private boolean mWentToSleep = false;
925
926    /**
927     * State of external call telling us if the lock screen is shown.
928     */
929    private boolean mLockScreenShown = false;
930
931    /**
932     * Set if we are shutting down the system, similar to sleeping.
933     */
934    boolean mShuttingDown = false;
935
936    /**
937     * Current sequence id for oom_adj computation traversal.
938     */
939    int mAdjSeq = 0;
940
941    /**
942     * Current sequence id for process LRU updating.
943     */
944    int mLruSeq = 0;
945
946    /**
947     * Keep track of the non-cached/empty process we last found, to help
948     * determine how to distribute cached/empty processes next time.
949     */
950    int mNumNonCachedProcs = 0;
951
952    /**
953     * Keep track of the number of cached hidden procs, to balance oom adj
954     * distribution between those and empty procs.
955     */
956    int mNumCachedHiddenProcs = 0;
957
958    /**
959     * Keep track of the number of service processes we last found, to
960     * determine on the next iteration which should be B services.
961     */
962    int mNumServiceProcs = 0;
963    int mNewNumAServiceProcs = 0;
964    int mNewNumServiceProcs = 0;
965
966    /**
967     * Allow the current computed overall memory level of the system to go down?
968     * This is set to false when we are killing processes for reasons other than
969     * memory management, so that the now smaller process list will not be taken as
970     * an indication that memory is tighter.
971     */
972    boolean mAllowLowerMemLevel = false;
973
974    /**
975     * The last computed memory level, for holding when we are in a state that
976     * processes are going away for other reasons.
977     */
978    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
979
980    /**
981     * The last total number of process we have, to determine if changes actually look
982     * like a shrinking number of process due to lower RAM.
983     */
984    int mLastNumProcesses;
985
986    /**
987     * The uptime of the last time we performed idle maintenance.
988     */
989    long mLastIdleTime = SystemClock.uptimeMillis();
990
991    /**
992     * Total time spent with RAM that has been added in the past since the last idle time.
993     */
994    long mLowRamTimeSinceLastIdle = 0;
995
996    /**
997     * If RAM is currently low, when that horrible situation started.
998     */
999    long mLowRamStartTime = 0;
1000
1001    /**
1002     * For reporting to battery stats the current top application.
1003     */
1004    private String mCurResumedPackage = null;
1005    private int mCurResumedUid = -1;
1006
1007    /**
1008     * For reporting to battery stats the apps currently running foreground
1009     * service.  The ProcessMap is package/uid tuples; each of these contain
1010     * an array of the currently foreground processes.
1011     */
1012    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1013            = new ProcessMap<ArrayList<ProcessRecord>>();
1014
1015    /**
1016     * This is set if we had to do a delayed dexopt of an app before launching
1017     * it, to increase the ANR timeouts in that case.
1018     */
1019    boolean mDidDexOpt;
1020
1021    /**
1022     * Set if the systemServer made a call to enterSafeMode.
1023     */
1024    boolean mSafeMode;
1025
1026    String mDebugApp = null;
1027    boolean mWaitForDebugger = false;
1028    boolean mDebugTransient = false;
1029    String mOrigDebugApp = null;
1030    boolean mOrigWaitForDebugger = false;
1031    boolean mAlwaysFinishActivities = false;
1032    IActivityController mController = null;
1033    String mProfileApp = null;
1034    ProcessRecord mProfileProc = null;
1035    String mProfileFile;
1036    ParcelFileDescriptor mProfileFd;
1037    int mProfileType = 0;
1038    boolean mAutoStopProfiler = false;
1039    String mOpenGlTraceApp = null;
1040
1041    static class ProcessChangeItem {
1042        static final int CHANGE_ACTIVITIES = 1<<0;
1043        static final int CHANGE_PROCESS_STATE = 1<<1;
1044        int changes;
1045        int uid;
1046        int pid;
1047        int processState;
1048        boolean foregroundActivities;
1049    }
1050
1051    final RemoteCallbackList<IProcessObserver> mProcessObservers
1052            = new RemoteCallbackList<IProcessObserver>();
1053    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1054
1055    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1056            = new ArrayList<ProcessChangeItem>();
1057    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1058            = new ArrayList<ProcessChangeItem>();
1059
1060    /**
1061     * Runtime CPU use collection thread.  This object's lock is used to
1062     * protect all related state.
1063     */
1064    final Thread mProcessCpuThread;
1065
1066    /**
1067     * Used to collect process stats when showing not responding dialog.
1068     * Protected by mProcessCpuThread.
1069     */
1070    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1071            MONITOR_THREAD_CPU_USAGE);
1072    final AtomicLong mLastCpuTime = new AtomicLong(0);
1073    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1074
1075    long mLastWriteTime = 0;
1076
1077    /**
1078     * Used to retain an update lock when the foreground activity is in
1079     * immersive mode.
1080     */
1081    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1082
1083    /**
1084     * Set to true after the system has finished booting.
1085     */
1086    boolean mBooted = false;
1087
1088    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1089    int mProcessLimitOverride = -1;
1090
1091    WindowManagerService mWindowManager;
1092
1093    final ActivityThread mSystemThread;
1094
1095    int mCurrentUserId = 0;
1096    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1097    private UserManagerService mUserManager;
1098
1099    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1100        final ProcessRecord mApp;
1101        final int mPid;
1102        final IApplicationThread mAppThread;
1103
1104        AppDeathRecipient(ProcessRecord app, int pid,
1105                IApplicationThread thread) {
1106            if (localLOGV) Slog.v(
1107                TAG, "New death recipient " + this
1108                + " for thread " + thread.asBinder());
1109            mApp = app;
1110            mPid = pid;
1111            mAppThread = thread;
1112        }
1113
1114        @Override
1115        public void binderDied() {
1116            if (localLOGV) Slog.v(
1117                TAG, "Death received in " + this
1118                + " for thread " + mAppThread.asBinder());
1119            synchronized(ActivityManagerService.this) {
1120                appDiedLocked(mApp, mPid, mAppThread);
1121            }
1122        }
1123    }
1124
1125    static final int SHOW_ERROR_MSG = 1;
1126    static final int SHOW_NOT_RESPONDING_MSG = 2;
1127    static final int SHOW_FACTORY_ERROR_MSG = 3;
1128    static final int UPDATE_CONFIGURATION_MSG = 4;
1129    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1130    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1131    static final int SERVICE_TIMEOUT_MSG = 12;
1132    static final int UPDATE_TIME_ZONE = 13;
1133    static final int SHOW_UID_ERROR_MSG = 14;
1134    static final int IM_FEELING_LUCKY_MSG = 15;
1135    static final int PROC_START_TIMEOUT_MSG = 20;
1136    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1137    static final int KILL_APPLICATION_MSG = 22;
1138    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1139    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1140    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1141    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1142    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1143    static final int CLEAR_DNS_CACHE_MSG = 28;
1144    static final int UPDATE_HTTP_PROXY_MSG = 29;
1145    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1146    static final int DISPATCH_PROCESSES_CHANGED = 31;
1147    static final int DISPATCH_PROCESS_DIED = 32;
1148    static final int REPORT_MEM_USAGE_MSG = 33;
1149    static final int REPORT_USER_SWITCH_MSG = 34;
1150    static final int CONTINUE_USER_SWITCH_MSG = 35;
1151    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1152    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1153    static final int PERSIST_URI_GRANTS_MSG = 38;
1154    static final int REQUEST_ALL_PSS_MSG = 39;
1155    static final int START_PROFILES_MSG = 40;
1156    static final int UPDATE_TIME = 41;
1157    static final int SYSTEM_USER_START_MSG = 42;
1158    static final int SYSTEM_USER_CURRENT_MSG = 43;
1159
1160    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1161    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1162    static final int FIRST_COMPAT_MODE_MSG = 300;
1163    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1164
1165    AlertDialog mUidAlert;
1166    CompatModeDialog mCompatModeDialog;
1167    long mLastMemUsageReportTime = 0;
1168
1169    private LockToAppRequestDialog mLockToAppRequest;
1170
1171    /**
1172     * Flag whether the current user is a "monkey", i.e. whether
1173     * the UI is driven by a UI automation tool.
1174     */
1175    private boolean mUserIsMonkey;
1176
1177    final ServiceThread mHandlerThread;
1178    final MainHandler mHandler;
1179
1180    final class MainHandler extends Handler {
1181        public MainHandler(Looper looper) {
1182            super(looper, null, true);
1183        }
1184
1185        @Override
1186        public void handleMessage(Message msg) {
1187            switch (msg.what) {
1188            case SHOW_ERROR_MSG: {
1189                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1190                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1191                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1192                synchronized (ActivityManagerService.this) {
1193                    ProcessRecord proc = (ProcessRecord)data.get("app");
1194                    AppErrorResult res = (AppErrorResult) data.get("result");
1195                    if (proc != null && proc.crashDialog != null) {
1196                        Slog.e(TAG, "App already has crash dialog: " + proc);
1197                        if (res != null) {
1198                            res.set(0);
1199                        }
1200                        return;
1201                    }
1202                    if (!showBackground && UserHandle.getAppId(proc.uid)
1203                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1204                            && proc.pid != MY_PID) {
1205                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1206                        if (res != null) {
1207                            res.set(0);
1208                        }
1209                        return;
1210                    }
1211                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1212                        Dialog d = new AppErrorDialog(mContext,
1213                                ActivityManagerService.this, res, proc);
1214                        d.show();
1215                        proc.crashDialog = d;
1216                    } else {
1217                        // The device is asleep, so just pretend that the user
1218                        // saw a crash dialog and hit "force quit".
1219                        if (res != null) {
1220                            res.set(0);
1221                        }
1222                    }
1223                }
1224
1225                ensureBootCompleted();
1226            } break;
1227            case SHOW_NOT_RESPONDING_MSG: {
1228                synchronized (ActivityManagerService.this) {
1229                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1230                    ProcessRecord proc = (ProcessRecord)data.get("app");
1231                    if (proc != null && proc.anrDialog != null) {
1232                        Slog.e(TAG, "App already has anr dialog: " + proc);
1233                        return;
1234                    }
1235
1236                    Intent intent = new Intent("android.intent.action.ANR");
1237                    if (!mProcessesReady) {
1238                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1239                                | Intent.FLAG_RECEIVER_FOREGROUND);
1240                    }
1241                    broadcastIntentLocked(null, null, intent,
1242                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1243                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1244
1245                    if (mShowDialogs) {
1246                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1247                                mContext, proc, (ActivityRecord)data.get("activity"),
1248                                msg.arg1 != 0);
1249                        d.show();
1250                        proc.anrDialog = d;
1251                    } else {
1252                        // Just kill the app if there is no dialog to be shown.
1253                        killAppAtUsersRequest(proc, null);
1254                    }
1255                }
1256
1257                ensureBootCompleted();
1258            } break;
1259            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1260                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1261                synchronized (ActivityManagerService.this) {
1262                    ProcessRecord proc = (ProcessRecord) data.get("app");
1263                    if (proc == null) {
1264                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1265                        break;
1266                    }
1267                    if (proc.crashDialog != null) {
1268                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1269                        return;
1270                    }
1271                    AppErrorResult res = (AppErrorResult) data.get("result");
1272                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1273                        Dialog d = new StrictModeViolationDialog(mContext,
1274                                ActivityManagerService.this, res, proc);
1275                        d.show();
1276                        proc.crashDialog = d;
1277                    } else {
1278                        // The device is asleep, so just pretend that the user
1279                        // saw a crash dialog and hit "force quit".
1280                        res.set(0);
1281                    }
1282                }
1283                ensureBootCompleted();
1284            } break;
1285            case SHOW_FACTORY_ERROR_MSG: {
1286                Dialog d = new FactoryErrorDialog(
1287                    mContext, msg.getData().getCharSequence("msg"));
1288                d.show();
1289                ensureBootCompleted();
1290            } break;
1291            case UPDATE_CONFIGURATION_MSG: {
1292                final ContentResolver resolver = mContext.getContentResolver();
1293                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1294            } break;
1295            case GC_BACKGROUND_PROCESSES_MSG: {
1296                synchronized (ActivityManagerService.this) {
1297                    performAppGcsIfAppropriateLocked();
1298                }
1299            } break;
1300            case WAIT_FOR_DEBUGGER_MSG: {
1301                synchronized (ActivityManagerService.this) {
1302                    ProcessRecord app = (ProcessRecord)msg.obj;
1303                    if (msg.arg1 != 0) {
1304                        if (!app.waitedForDebugger) {
1305                            Dialog d = new AppWaitingForDebuggerDialog(
1306                                    ActivityManagerService.this,
1307                                    mContext, app);
1308                            app.waitDialog = d;
1309                            app.waitedForDebugger = true;
1310                            d.show();
1311                        }
1312                    } else {
1313                        if (app.waitDialog != null) {
1314                            app.waitDialog.dismiss();
1315                            app.waitDialog = null;
1316                        }
1317                    }
1318                }
1319            } break;
1320            case SERVICE_TIMEOUT_MSG: {
1321                if (mDidDexOpt) {
1322                    mDidDexOpt = false;
1323                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1324                    nmsg.obj = msg.obj;
1325                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1326                    return;
1327                }
1328                mServices.serviceTimeout((ProcessRecord)msg.obj);
1329            } break;
1330            case UPDATE_TIME_ZONE: {
1331                synchronized (ActivityManagerService.this) {
1332                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1333                        ProcessRecord r = mLruProcesses.get(i);
1334                        if (r.thread != null) {
1335                            try {
1336                                r.thread.updateTimeZone();
1337                            } catch (RemoteException ex) {
1338                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1339                            }
1340                        }
1341                    }
1342                }
1343            } break;
1344            case CLEAR_DNS_CACHE_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1347                        ProcessRecord r = mLruProcesses.get(i);
1348                        if (r.thread != null) {
1349                            try {
1350                                r.thread.clearDnsCache();
1351                            } catch (RemoteException ex) {
1352                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1353                            }
1354                        }
1355                    }
1356                }
1357            } break;
1358            case UPDATE_HTTP_PROXY_MSG: {
1359                ProxyInfo proxy = (ProxyInfo)msg.obj;
1360                String host = "";
1361                String port = "";
1362                String exclList = "";
1363                Uri pacFileUrl = Uri.EMPTY;
1364                if (proxy != null) {
1365                    host = proxy.getHost();
1366                    port = Integer.toString(proxy.getPort());
1367                    exclList = proxy.getExclusionListAsString();
1368                    pacFileUrl = proxy.getPacFileUrl();
1369                }
1370                synchronized (ActivityManagerService.this) {
1371                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1372                        ProcessRecord r = mLruProcesses.get(i);
1373                        if (r.thread != null) {
1374                            try {
1375                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1376                            } catch (RemoteException ex) {
1377                                Slog.w(TAG, "Failed to update http proxy for: " +
1378                                        r.info.processName);
1379                            }
1380                        }
1381                    }
1382                }
1383            } break;
1384            case SHOW_UID_ERROR_MSG: {
1385                String title = "System UIDs Inconsistent";
1386                String text = "UIDs on the system are inconsistent, you need to wipe your"
1387                        + " data partition or your device will be unstable.";
1388                Log.e(TAG, title + ": " + text);
1389                if (mShowDialogs) {
1390                    // XXX This is a temporary dialog, no need to localize.
1391                    AlertDialog d = new BaseErrorDialog(mContext);
1392                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1393                    d.setCancelable(false);
1394                    d.setTitle(title);
1395                    d.setMessage(text);
1396                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1397                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1398                    mUidAlert = d;
1399                    d.show();
1400                }
1401            } break;
1402            case IM_FEELING_LUCKY_MSG: {
1403                if (mUidAlert != null) {
1404                    mUidAlert.dismiss();
1405                    mUidAlert = null;
1406                }
1407            } break;
1408            case PROC_START_TIMEOUT_MSG: {
1409                if (mDidDexOpt) {
1410                    mDidDexOpt = false;
1411                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1412                    nmsg.obj = msg.obj;
1413                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1414                    return;
1415                }
1416                ProcessRecord app = (ProcessRecord)msg.obj;
1417                synchronized (ActivityManagerService.this) {
1418                    processStartTimedOutLocked(app);
1419                }
1420            } break;
1421            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1422                synchronized (ActivityManagerService.this) {
1423                    doPendingActivityLaunchesLocked(true);
1424                }
1425            } break;
1426            case KILL_APPLICATION_MSG: {
1427                synchronized (ActivityManagerService.this) {
1428                    int appid = msg.arg1;
1429                    boolean restart = (msg.arg2 == 1);
1430                    Bundle bundle = (Bundle)msg.obj;
1431                    String pkg = bundle.getString("pkg");
1432                    String reason = bundle.getString("reason");
1433                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1434                            false, UserHandle.USER_ALL, reason);
1435                }
1436            } break;
1437            case FINALIZE_PENDING_INTENT_MSG: {
1438                ((PendingIntentRecord)msg.obj).completeFinalize();
1439            } break;
1440            case POST_HEAVY_NOTIFICATION_MSG: {
1441                INotificationManager inm = NotificationManager.getService();
1442                if (inm == null) {
1443                    return;
1444                }
1445
1446                ActivityRecord root = (ActivityRecord)msg.obj;
1447                ProcessRecord process = root.app;
1448                if (process == null) {
1449                    return;
1450                }
1451
1452                try {
1453                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1454                    String text = mContext.getString(R.string.heavy_weight_notification,
1455                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1456                    Notification notification = new Notification();
1457                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1458                    notification.when = 0;
1459                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1460                    notification.tickerText = text;
1461                    notification.defaults = 0; // please be quiet
1462                    notification.sound = null;
1463                    notification.vibrate = null;
1464                    notification.setLatestEventInfo(context, text,
1465                            mContext.getText(R.string.heavy_weight_notification_detail),
1466                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1467                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1468                                    new UserHandle(root.userId)));
1469
1470                    try {
1471                        int[] outId = new int[1];
1472                        inm.enqueueNotificationWithTag("android", "android", null,
1473                                R.string.heavy_weight_notification,
1474                                notification, outId, root.userId);
1475                    } catch (RuntimeException e) {
1476                        Slog.w(ActivityManagerService.TAG,
1477                                "Error showing notification for heavy-weight app", e);
1478                    } catch (RemoteException e) {
1479                    }
1480                } catch (NameNotFoundException e) {
1481                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1482                }
1483            } break;
1484            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1485                INotificationManager inm = NotificationManager.getService();
1486                if (inm == null) {
1487                    return;
1488                }
1489                try {
1490                    inm.cancelNotificationWithTag("android", null,
1491                            R.string.heavy_weight_notification,  msg.arg1);
1492                } catch (RuntimeException e) {
1493                    Slog.w(ActivityManagerService.TAG,
1494                            "Error canceling notification for service", e);
1495                } catch (RemoteException e) {
1496                }
1497            } break;
1498            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1499                synchronized (ActivityManagerService.this) {
1500                    checkExcessivePowerUsageLocked(true);
1501                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1502                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1503                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1504                }
1505            } break;
1506            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1507                synchronized (ActivityManagerService.this) {
1508                    ActivityRecord ar = (ActivityRecord)msg.obj;
1509                    if (mCompatModeDialog != null) {
1510                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1511                                ar.info.applicationInfo.packageName)) {
1512                            return;
1513                        }
1514                        mCompatModeDialog.dismiss();
1515                        mCompatModeDialog = null;
1516                    }
1517                    if (ar != null && false) {
1518                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1519                                ar.packageName)) {
1520                            int mode = mCompatModePackages.computeCompatModeLocked(
1521                                    ar.info.applicationInfo);
1522                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1523                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1524                                mCompatModeDialog = new CompatModeDialog(
1525                                        ActivityManagerService.this, mContext,
1526                                        ar.info.applicationInfo);
1527                                mCompatModeDialog.show();
1528                            }
1529                        }
1530                    }
1531                }
1532                break;
1533            }
1534            case DISPATCH_PROCESSES_CHANGED: {
1535                dispatchProcessesChanged();
1536                break;
1537            }
1538            case DISPATCH_PROCESS_DIED: {
1539                final int pid = msg.arg1;
1540                final int uid = msg.arg2;
1541                dispatchProcessDied(pid, uid);
1542                break;
1543            }
1544            case REPORT_MEM_USAGE_MSG: {
1545                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1546                Thread thread = new Thread() {
1547                    @Override public void run() {
1548                        final SparseArray<ProcessMemInfo> infoMap
1549                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1550                        for (int i=0, N=memInfos.size(); i<N; i++) {
1551                            ProcessMemInfo mi = memInfos.get(i);
1552                            infoMap.put(mi.pid, mi);
1553                        }
1554                        updateCpuStatsNow();
1555                        synchronized (mProcessCpuThread) {
1556                            final int N = mProcessCpuTracker.countStats();
1557                            for (int i=0; i<N; i++) {
1558                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1559                                if (st.vsize > 0) {
1560                                    long pss = Debug.getPss(st.pid, null);
1561                                    if (pss > 0) {
1562                                        if (infoMap.indexOfKey(st.pid) < 0) {
1563                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1564                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1565                                            mi.pss = pss;
1566                                            memInfos.add(mi);
1567                                        }
1568                                    }
1569                                }
1570                            }
1571                        }
1572
1573                        long totalPss = 0;
1574                        for (int i=0, N=memInfos.size(); i<N; i++) {
1575                            ProcessMemInfo mi = memInfos.get(i);
1576                            if (mi.pss == 0) {
1577                                mi.pss = Debug.getPss(mi.pid, null);
1578                            }
1579                            totalPss += mi.pss;
1580                        }
1581                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1582                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1583                                if (lhs.oomAdj != rhs.oomAdj) {
1584                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1585                                }
1586                                if (lhs.pss != rhs.pss) {
1587                                    return lhs.pss < rhs.pss ? 1 : -1;
1588                                }
1589                                return 0;
1590                            }
1591                        });
1592
1593                        StringBuilder tag = new StringBuilder(128);
1594                        StringBuilder stack = new StringBuilder(128);
1595                        tag.append("Low on memory -- ");
1596                        appendMemBucket(tag, totalPss, "total", false);
1597                        appendMemBucket(stack, totalPss, "total", true);
1598
1599                        StringBuilder logBuilder = new StringBuilder(1024);
1600                        logBuilder.append("Low on memory:\n");
1601
1602                        boolean firstLine = true;
1603                        int lastOomAdj = Integer.MIN_VALUE;
1604                        for (int i=0, N=memInfos.size(); i<N; i++) {
1605                            ProcessMemInfo mi = memInfos.get(i);
1606
1607                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1608                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1609                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1610                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1611                                if (lastOomAdj != mi.oomAdj) {
1612                                    lastOomAdj = mi.oomAdj;
1613                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1614                                        tag.append(" / ");
1615                                    }
1616                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1617                                        if (firstLine) {
1618                                            stack.append(":");
1619                                            firstLine = false;
1620                                        }
1621                                        stack.append("\n\t at ");
1622                                    } else {
1623                                        stack.append("$");
1624                                    }
1625                                } else {
1626                                    tag.append(" ");
1627                                    stack.append("$");
1628                                }
1629                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1630                                    appendMemBucket(tag, mi.pss, mi.name, false);
1631                                }
1632                                appendMemBucket(stack, mi.pss, mi.name, true);
1633                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1634                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1635                                    stack.append("(");
1636                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1637                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1638                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1639                                            stack.append(":");
1640                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1641                                        }
1642                                    }
1643                                    stack.append(")");
1644                                }
1645                            }
1646
1647                            logBuilder.append("  ");
1648                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1649                            logBuilder.append(' ');
1650                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1651                            logBuilder.append(' ');
1652                            ProcessList.appendRamKb(logBuilder, mi.pss);
1653                            logBuilder.append(" kB: ");
1654                            logBuilder.append(mi.name);
1655                            logBuilder.append(" (");
1656                            logBuilder.append(mi.pid);
1657                            logBuilder.append(") ");
1658                            logBuilder.append(mi.adjType);
1659                            logBuilder.append('\n');
1660                            if (mi.adjReason != null) {
1661                                logBuilder.append("                      ");
1662                                logBuilder.append(mi.adjReason);
1663                                logBuilder.append('\n');
1664                            }
1665                        }
1666
1667                        logBuilder.append("           ");
1668                        ProcessList.appendRamKb(logBuilder, totalPss);
1669                        logBuilder.append(" kB: TOTAL\n");
1670
1671                        long[] infos = new long[Debug.MEMINFO_COUNT];
1672                        Debug.getMemInfo(infos);
1673                        logBuilder.append("  MemInfo: ");
1674                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1675                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1676                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1677                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1678                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1679                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1680                            logBuilder.append("  ZRAM: ");
1681                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1682                            logBuilder.append(" kB RAM, ");
1683                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1684                            logBuilder.append(" kB swap total, ");
1685                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1686                            logBuilder.append(" kB swap free\n");
1687                        }
1688                        Slog.i(TAG, logBuilder.toString());
1689
1690                        StringBuilder dropBuilder = new StringBuilder(1024);
1691                        /*
1692                        StringWriter oomSw = new StringWriter();
1693                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1694                        StringWriter catSw = new StringWriter();
1695                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1696                        String[] emptyArgs = new String[] { };
1697                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1698                        oomPw.flush();
1699                        String oomString = oomSw.toString();
1700                        */
1701                        dropBuilder.append(stack);
1702                        dropBuilder.append('\n');
1703                        dropBuilder.append('\n');
1704                        dropBuilder.append(logBuilder);
1705                        dropBuilder.append('\n');
1706                        /*
1707                        dropBuilder.append(oomString);
1708                        dropBuilder.append('\n');
1709                        */
1710                        StringWriter catSw = new StringWriter();
1711                        synchronized (ActivityManagerService.this) {
1712                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1713                            String[] emptyArgs = new String[] { };
1714                            catPw.println();
1715                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1716                            catPw.println();
1717                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1718                                    false, false, null);
1719                            catPw.println();
1720                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1721                            catPw.flush();
1722                        }
1723                        dropBuilder.append(catSw.toString());
1724                        addErrorToDropBox("lowmem", null, "system_server", null,
1725                                null, tag.toString(), dropBuilder.toString(), null, null);
1726                        //Slog.i(TAG, "Sent to dropbox:");
1727                        //Slog.i(TAG, dropBuilder.toString());
1728                        synchronized (ActivityManagerService.this) {
1729                            long now = SystemClock.uptimeMillis();
1730                            if (mLastMemUsageReportTime < now) {
1731                                mLastMemUsageReportTime = now;
1732                            }
1733                        }
1734                    }
1735                };
1736                thread.start();
1737                break;
1738            }
1739            case REPORT_USER_SWITCH_MSG: {
1740                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1741                break;
1742            }
1743            case CONTINUE_USER_SWITCH_MSG: {
1744                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1745                break;
1746            }
1747            case USER_SWITCH_TIMEOUT_MSG: {
1748                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1749                break;
1750            }
1751            case IMMERSIVE_MODE_LOCK_MSG: {
1752                final boolean nextState = (msg.arg1 != 0);
1753                if (mUpdateLock.isHeld() != nextState) {
1754                    if (DEBUG_IMMERSIVE) {
1755                        final ActivityRecord r = (ActivityRecord) msg.obj;
1756                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1757                    }
1758                    if (nextState) {
1759                        mUpdateLock.acquire();
1760                    } else {
1761                        mUpdateLock.release();
1762                    }
1763                }
1764                break;
1765            }
1766            case PERSIST_URI_GRANTS_MSG: {
1767                writeGrantedUriPermissions();
1768                break;
1769            }
1770            case REQUEST_ALL_PSS_MSG: {
1771                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1772                break;
1773            }
1774            case START_PROFILES_MSG: {
1775                synchronized (ActivityManagerService.this) {
1776                    startProfilesLocked();
1777                }
1778                break;
1779            }
1780            case UPDATE_TIME: {
1781                synchronized (ActivityManagerService.this) {
1782                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1783                        ProcessRecord r = mLruProcesses.get(i);
1784                        if (r.thread != null) {
1785                            try {
1786                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1787                            } catch (RemoteException ex) {
1788                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1789                            }
1790                        }
1791                    }
1792                }
1793                break;
1794            }
1795            case SYSTEM_USER_START_MSG: {
1796                mSystemServiceManager.startUser(msg.arg1);
1797                break;
1798            }
1799            case SYSTEM_USER_CURRENT_MSG: {
1800                mSystemServiceManager.switchUser(msg.arg1);
1801                break;
1802            }
1803            }
1804        }
1805    };
1806
1807    static final int COLLECT_PSS_BG_MSG = 1;
1808
1809    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1810        @Override
1811        public void handleMessage(Message msg) {
1812            switch (msg.what) {
1813            case COLLECT_PSS_BG_MSG: {
1814                int i=0, num=0;
1815                long start = SystemClock.uptimeMillis();
1816                long[] tmp = new long[1];
1817                do {
1818                    ProcessRecord proc;
1819                    int procState;
1820                    int pid;
1821                    synchronized (ActivityManagerService.this) {
1822                        if (i >= mPendingPssProcesses.size()) {
1823                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1824                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1825                            mPendingPssProcesses.clear();
1826                            return;
1827                        }
1828                        proc = mPendingPssProcesses.get(i);
1829                        procState = proc.pssProcState;
1830                        if (proc.thread != null && procState == proc.setProcState) {
1831                            pid = proc.pid;
1832                        } else {
1833                            proc = null;
1834                            pid = 0;
1835                        }
1836                        i++;
1837                    }
1838                    if (proc != null) {
1839                        long pss = Debug.getPss(pid, tmp);
1840                        synchronized (ActivityManagerService.this) {
1841                            if (proc.thread != null && proc.setProcState == procState
1842                                    && proc.pid == pid) {
1843                                num++;
1844                                proc.lastPssTime = SystemClock.uptimeMillis();
1845                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1846                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1847                                        + ": " + pss + " lastPss=" + proc.lastPss
1848                                        + " state=" + ProcessList.makeProcStateString(procState));
1849                                if (proc.initialIdlePss == 0) {
1850                                    proc.initialIdlePss = pss;
1851                                }
1852                                proc.lastPss = pss;
1853                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1854                                    proc.lastCachedPss = pss;
1855                                }
1856                            }
1857                        }
1858                    }
1859                } while (true);
1860            }
1861            }
1862        }
1863    };
1864
1865    /**
1866     * Monitor for package changes and update our internal state.
1867     */
1868    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1869        @Override
1870        public void onPackageRemoved(String packageName, int uid) {
1871            // Remove all tasks with activities in the specified package from the list of recent tasks
1872            synchronized (ActivityManagerService.this) {
1873                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1874                    TaskRecord tr = mRecentTasks.get(i);
1875                    ComponentName cn = tr.intent.getComponent();
1876                    if (cn != null && cn.getPackageName().equals(packageName)) {
1877                        // If the package name matches, remove the task and kill the process
1878                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1879                    }
1880                }
1881            }
1882        }
1883
1884        @Override
1885        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1886            onPackageModified(packageName);
1887            return true;
1888        }
1889
1890        @Override
1891        public void onPackageModified(String packageName) {
1892            final PackageManager pm = mContext.getPackageManager();
1893            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1894                    new ArrayList<Pair<Intent, Integer>>();
1895            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1896            // Copy the list of recent tasks so that we don't hold onto the lock on
1897            // ActivityManagerService for long periods while checking if components exist.
1898            synchronized (ActivityManagerService.this) {
1899                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1900                    TaskRecord tr = mRecentTasks.get(i);
1901                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1902                }
1903            }
1904            // Check the recent tasks and filter out all tasks with components that no longer exist.
1905            Intent tmpI = new Intent();
1906            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1907                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1908                ComponentName cn = p.first.getComponent();
1909                if (cn != null && cn.getPackageName().equals(packageName)) {
1910                    try {
1911                        // Add the task to the list to remove if the component no longer exists
1912                        tmpI.setComponent(cn);
1913                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1914                            tasksToRemove.add(p.second);
1915                        }
1916                    } catch (Exception e) {}
1917                }
1918            }
1919            // Prune all the tasks with removed components from the list of recent tasks
1920            synchronized (ActivityManagerService.this) {
1921                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1922                    // Remove the task but don't kill the process (since other components in that
1923                    // package may still be running and in the background)
1924                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1925                }
1926            }
1927        }
1928
1929        @Override
1930        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1931            // Force stop the specified packages
1932            if (packages != null) {
1933                for (String pkg : packages) {
1934                    synchronized (ActivityManagerService.this) {
1935                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1936                                "finished booting")) {
1937                            return true;
1938                        }
1939                    }
1940                }
1941            }
1942            return false;
1943        }
1944    };
1945
1946    public void setSystemProcess() {
1947        try {
1948            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1949            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1950            ServiceManager.addService("meminfo", new MemBinder(this));
1951            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1952            ServiceManager.addService("dbinfo", new DbBinder(this));
1953            if (MONITOR_CPU_USAGE) {
1954                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1955            }
1956            ServiceManager.addService("permission", new PermissionController(this));
1957
1958            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1959                    "android", STOCK_PM_FLAGS);
1960            mSystemThread.installSystemApplicationInfo(info);
1961
1962            synchronized (this) {
1963                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1964                app.persistent = true;
1965                app.pid = MY_PID;
1966                app.maxAdj = ProcessList.SYSTEM_ADJ;
1967                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1968                mProcessNames.put(app.processName, app.uid, app);
1969                synchronized (mPidsSelfLocked) {
1970                    mPidsSelfLocked.put(app.pid, app);
1971                }
1972                updateLruProcessLocked(app, false, null);
1973                updateOomAdjLocked();
1974            }
1975        } catch (PackageManager.NameNotFoundException e) {
1976            throw new RuntimeException(
1977                    "Unable to find android system package", e);
1978        }
1979    }
1980
1981    public void setWindowManager(WindowManagerService wm) {
1982        mWindowManager = wm;
1983        mStackSupervisor.setWindowManager(wm);
1984    }
1985
1986    public void startObservingNativeCrashes() {
1987        final NativeCrashListener ncl = new NativeCrashListener(this);
1988        ncl.start();
1989    }
1990
1991    public IAppOpsService getAppOpsService() {
1992        return mAppOpsService;
1993    }
1994
1995    static class MemBinder extends Binder {
1996        ActivityManagerService mActivityManagerService;
1997        MemBinder(ActivityManagerService activityManagerService) {
1998            mActivityManagerService = activityManagerService;
1999        }
2000
2001        @Override
2002        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2003            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2004                    != PackageManager.PERMISSION_GRANTED) {
2005                pw.println("Permission Denial: can't dump meminfo from from pid="
2006                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2007                        + " without permission " + android.Manifest.permission.DUMP);
2008                return;
2009            }
2010
2011            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2012        }
2013    }
2014
2015    static class GraphicsBinder extends Binder {
2016        ActivityManagerService mActivityManagerService;
2017        GraphicsBinder(ActivityManagerService activityManagerService) {
2018            mActivityManagerService = activityManagerService;
2019        }
2020
2021        @Override
2022        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2023            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2024                    != PackageManager.PERMISSION_GRANTED) {
2025                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2026                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2027                        + " without permission " + android.Manifest.permission.DUMP);
2028                return;
2029            }
2030
2031            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2032        }
2033    }
2034
2035    static class DbBinder extends Binder {
2036        ActivityManagerService mActivityManagerService;
2037        DbBinder(ActivityManagerService activityManagerService) {
2038            mActivityManagerService = activityManagerService;
2039        }
2040
2041        @Override
2042        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2043            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2044                    != PackageManager.PERMISSION_GRANTED) {
2045                pw.println("Permission Denial: can't dump dbinfo from from pid="
2046                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2047                        + " without permission " + android.Manifest.permission.DUMP);
2048                return;
2049            }
2050
2051            mActivityManagerService.dumpDbInfo(fd, pw, args);
2052        }
2053    }
2054
2055    static class CpuBinder extends Binder {
2056        ActivityManagerService mActivityManagerService;
2057        CpuBinder(ActivityManagerService activityManagerService) {
2058            mActivityManagerService = activityManagerService;
2059        }
2060
2061        @Override
2062        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2063            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2064                    != PackageManager.PERMISSION_GRANTED) {
2065                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2066                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2067                        + " without permission " + android.Manifest.permission.DUMP);
2068                return;
2069            }
2070
2071            synchronized (mActivityManagerService.mProcessCpuThread) {
2072                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2073                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2074                        SystemClock.uptimeMillis()));
2075            }
2076        }
2077    }
2078
2079    public static final class Lifecycle extends SystemService {
2080        private final ActivityManagerService mService;
2081
2082        public Lifecycle(Context context) {
2083            super(context);
2084            mService = new ActivityManagerService(context);
2085        }
2086
2087        @Override
2088        public void onStart() {
2089            mService.start();
2090        }
2091
2092        public ActivityManagerService getService() {
2093            return mService;
2094        }
2095    }
2096
2097    // Note: This method is invoked on the main thread but may need to attach various
2098    // handlers to other threads.  So take care to be explicit about the looper.
2099    public ActivityManagerService(Context systemContext) {
2100        mContext = systemContext;
2101        mFactoryTest = FactoryTest.getMode();
2102        mSystemThread = ActivityThread.currentActivityThread();
2103
2104        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2105
2106        mHandlerThread = new ServiceThread(TAG,
2107                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2108        mHandlerThread.start();
2109        mHandler = new MainHandler(mHandlerThread.getLooper());
2110
2111        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2112                "foreground", BROADCAST_FG_TIMEOUT, false);
2113        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2114                "background", BROADCAST_BG_TIMEOUT, true);
2115        mBroadcastQueues[0] = mFgBroadcastQueue;
2116        mBroadcastQueues[1] = mBgBroadcastQueue;
2117
2118        mServices = new ActiveServices(this);
2119        mProviderMap = new ProviderMap(this);
2120
2121        // TODO: Move creation of battery stats service outside of activity manager service.
2122        File dataDir = Environment.getDataDirectory();
2123        File systemDir = new File(dataDir, "system");
2124        systemDir.mkdirs();
2125        mBatteryStatsService = new BatteryStatsService(new File(
2126                systemDir, "batterystats.bin").toString(), mHandler);
2127        mBatteryStatsService.getActiveStatistics().readLocked();
2128        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2129        mOnBattery = DEBUG_POWER ? true
2130                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2131        mBatteryStatsService.getActiveStatistics().setCallback(this);
2132
2133        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2134
2135        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2136        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2137
2138        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2139
2140        // User 0 is the first and only user that runs at boot.
2141        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2142        mUserLru.add(Integer.valueOf(0));
2143        updateStartedUserArrayLocked();
2144
2145        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2146            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2147
2148        mConfiguration.setToDefaults();
2149        mConfiguration.setLocale(Locale.getDefault());
2150
2151        mConfigurationSeq = mConfiguration.seq = 1;
2152        mProcessCpuTracker.init();
2153
2154        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2155        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2156        mStackSupervisor = new ActivityStackSupervisor(this);
2157        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2158
2159        mProcessCpuThread = new Thread("CpuTracker") {
2160            @Override
2161            public void run() {
2162                while (true) {
2163                    try {
2164                        try {
2165                            synchronized(this) {
2166                                final long now = SystemClock.uptimeMillis();
2167                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2168                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2169                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2170                                //        + ", write delay=" + nextWriteDelay);
2171                                if (nextWriteDelay < nextCpuDelay) {
2172                                    nextCpuDelay = nextWriteDelay;
2173                                }
2174                                if (nextCpuDelay > 0) {
2175                                    mProcessCpuMutexFree.set(true);
2176                                    this.wait(nextCpuDelay);
2177                                }
2178                            }
2179                        } catch (InterruptedException e) {
2180                        }
2181                        updateCpuStatsNow();
2182                    } catch (Exception e) {
2183                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2184                    }
2185                }
2186            }
2187        };
2188
2189        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2190
2191        Watchdog.getInstance().addMonitor(this);
2192        Watchdog.getInstance().addThread(mHandler);
2193    }
2194
2195    public void setSystemServiceManager(SystemServiceManager mgr) {
2196        mSystemServiceManager = mgr;
2197    }
2198
2199    private void start() {
2200        mProcessCpuThread.start();
2201
2202        mBatteryStatsService.publish(mContext);
2203        mUsageStatsService.publish(mContext);
2204        mAppOpsService.publish(mContext);
2205        Slog.d("AppOps", "AppOpsService published");
2206        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2207    }
2208
2209    public void initPowerManagement() {
2210        mStackSupervisor.initPowerManagement();
2211        mBatteryStatsService.initPowerManagement();
2212    }
2213
2214    @Override
2215    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2216            throws RemoteException {
2217        if (code == SYSPROPS_TRANSACTION) {
2218            // We need to tell all apps about the system property change.
2219            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2220            synchronized(this) {
2221                final int NP = mProcessNames.getMap().size();
2222                for (int ip=0; ip<NP; ip++) {
2223                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2224                    final int NA = apps.size();
2225                    for (int ia=0; ia<NA; ia++) {
2226                        ProcessRecord app = apps.valueAt(ia);
2227                        if (app.thread != null) {
2228                            procs.add(app.thread.asBinder());
2229                        }
2230                    }
2231                }
2232            }
2233
2234            int N = procs.size();
2235            for (int i=0; i<N; i++) {
2236                Parcel data2 = Parcel.obtain();
2237                try {
2238                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2239                } catch (RemoteException e) {
2240                }
2241                data2.recycle();
2242            }
2243        }
2244        try {
2245            return super.onTransact(code, data, reply, flags);
2246        } catch (RuntimeException e) {
2247            // The activity manager only throws security exceptions, so let's
2248            // log all others.
2249            if (!(e instanceof SecurityException)) {
2250                Slog.wtf(TAG, "Activity Manager Crash", e);
2251            }
2252            throw e;
2253        }
2254    }
2255
2256    void updateCpuStats() {
2257        final long now = SystemClock.uptimeMillis();
2258        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2259            return;
2260        }
2261        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2262            synchronized (mProcessCpuThread) {
2263                mProcessCpuThread.notify();
2264            }
2265        }
2266    }
2267
2268    void updateCpuStatsNow() {
2269        synchronized (mProcessCpuThread) {
2270            mProcessCpuMutexFree.set(false);
2271            final long now = SystemClock.uptimeMillis();
2272            boolean haveNewCpuStats = false;
2273
2274            if (MONITOR_CPU_USAGE &&
2275                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2276                mLastCpuTime.set(now);
2277                haveNewCpuStats = true;
2278                mProcessCpuTracker.update();
2279                //Slog.i(TAG, mProcessCpu.printCurrentState());
2280                //Slog.i(TAG, "Total CPU usage: "
2281                //        + mProcessCpu.getTotalCpuPercent() + "%");
2282
2283                // Slog the cpu usage if the property is set.
2284                if ("true".equals(SystemProperties.get("events.cpu"))) {
2285                    int user = mProcessCpuTracker.getLastUserTime();
2286                    int system = mProcessCpuTracker.getLastSystemTime();
2287                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2288                    int irq = mProcessCpuTracker.getLastIrqTime();
2289                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2290                    int idle = mProcessCpuTracker.getLastIdleTime();
2291
2292                    int total = user + system + iowait + irq + softIrq + idle;
2293                    if (total == 0) total = 1;
2294
2295                    EventLog.writeEvent(EventLogTags.CPU,
2296                            ((user+system+iowait+irq+softIrq) * 100) / total,
2297                            (user * 100) / total,
2298                            (system * 100) / total,
2299                            (iowait * 100) / total,
2300                            (irq * 100) / total,
2301                            (softIrq * 100) / total);
2302                }
2303            }
2304
2305            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2306            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2307            synchronized(bstats) {
2308                synchronized(mPidsSelfLocked) {
2309                    if (haveNewCpuStats) {
2310                        if (mOnBattery) {
2311                            int perc = bstats.startAddingCpuLocked();
2312                            int totalUTime = 0;
2313                            int totalSTime = 0;
2314                            final int N = mProcessCpuTracker.countStats();
2315                            for (int i=0; i<N; i++) {
2316                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2317                                if (!st.working) {
2318                                    continue;
2319                                }
2320                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2321                                int otherUTime = (st.rel_utime*perc)/100;
2322                                int otherSTime = (st.rel_stime*perc)/100;
2323                                totalUTime += otherUTime;
2324                                totalSTime += otherSTime;
2325                                if (pr != null) {
2326                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2327                                    if (ps == null || !ps.isActive()) {
2328                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2329                                                pr.info.uid, pr.processName);
2330                                    }
2331                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2332                                            st.rel_stime-otherSTime);
2333                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2334                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2335                                } else {
2336                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2337                                    if (ps == null || !ps.isActive()) {
2338                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2339                                                bstats.mapUid(st.uid), st.name);
2340                                    }
2341                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2342                                            st.rel_stime-otherSTime);
2343                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2344                                }
2345                            }
2346                            bstats.finishAddingCpuLocked(perc, totalUTime,
2347                                    totalSTime, cpuSpeedTimes);
2348                        }
2349                    }
2350                }
2351
2352                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2353                    mLastWriteTime = now;
2354                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2355                }
2356            }
2357        }
2358    }
2359
2360    @Override
2361    public void batteryNeedsCpuUpdate() {
2362        updateCpuStatsNow();
2363    }
2364
2365    @Override
2366    public void batteryPowerChanged(boolean onBattery) {
2367        // When plugging in, update the CPU stats first before changing
2368        // the plug state.
2369        updateCpuStatsNow();
2370        synchronized (this) {
2371            synchronized(mPidsSelfLocked) {
2372                mOnBattery = DEBUG_POWER ? true : onBattery;
2373            }
2374        }
2375    }
2376
2377    /**
2378     * Initialize the application bind args. These are passed to each
2379     * process when the bindApplication() IPC is sent to the process. They're
2380     * lazily setup to make sure the services are running when they're asked for.
2381     */
2382    private HashMap<String, IBinder> getCommonServicesLocked() {
2383        if (mAppBindArgs == null) {
2384            mAppBindArgs = new HashMap<String, IBinder>();
2385
2386            // Setup the application init args
2387            mAppBindArgs.put("package", ServiceManager.getService("package"));
2388            mAppBindArgs.put("window", ServiceManager.getService("window"));
2389            mAppBindArgs.put(Context.ALARM_SERVICE,
2390                    ServiceManager.getService(Context.ALARM_SERVICE));
2391        }
2392        return mAppBindArgs;
2393    }
2394
2395    final void setFocusedActivityLocked(ActivityRecord r) {
2396        if (mFocusedActivity != r) {
2397            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2398            mFocusedActivity = r;
2399            if (r.task != null && r.task.voiceInteractor != null) {
2400                startRunningVoiceLocked();
2401            } else {
2402                finishRunningVoiceLocked();
2403            }
2404            mStackSupervisor.setFocusedStack(r);
2405            if (r != null) {
2406                mWindowManager.setFocusedApp(r.appToken, true);
2407            }
2408            applyUpdateLockStateLocked(r);
2409        }
2410    }
2411
2412    final void clearFocusedActivity(ActivityRecord r) {
2413        if (mFocusedActivity == r) {
2414            mFocusedActivity = null;
2415        }
2416    }
2417
2418    @Override
2419    public void setFocusedStack(int stackId) {
2420        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2421        synchronized (ActivityManagerService.this) {
2422            ActivityStack stack = mStackSupervisor.getStack(stackId);
2423            if (stack != null) {
2424                ActivityRecord r = stack.topRunningActivityLocked(null);
2425                if (r != null) {
2426                    setFocusedActivityLocked(r);
2427                }
2428            }
2429        }
2430    }
2431
2432    @Override
2433    public void notifyActivityDrawn(IBinder token) {
2434        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2435        synchronized (this) {
2436            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2437            if (r != null) {
2438                r.task.stack.notifyActivityDrawnLocked(r);
2439            }
2440        }
2441    }
2442
2443    final void applyUpdateLockStateLocked(ActivityRecord r) {
2444        // Modifications to the UpdateLock state are done on our handler, outside
2445        // the activity manager's locks.  The new state is determined based on the
2446        // state *now* of the relevant activity record.  The object is passed to
2447        // the handler solely for logging detail, not to be consulted/modified.
2448        final boolean nextState = r != null && r.immersive;
2449        mHandler.sendMessage(
2450                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2451    }
2452
2453    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2454        Message msg = Message.obtain();
2455        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2456        msg.obj = r.task.askedCompatMode ? null : r;
2457        mHandler.sendMessage(msg);
2458    }
2459
2460    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2461            String what, Object obj, ProcessRecord srcApp) {
2462        app.lastActivityTime = now;
2463
2464        if (app.activities.size() > 0) {
2465            // Don't want to touch dependent processes that are hosting activities.
2466            return index;
2467        }
2468
2469        int lrui = mLruProcesses.lastIndexOf(app);
2470        if (lrui < 0) {
2471            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2472                    + what + " " + obj + " from " + srcApp);
2473            return index;
2474        }
2475
2476        if (lrui >= index) {
2477            // Don't want to cause this to move dependent processes *back* in the
2478            // list as if they were less frequently used.
2479            return index;
2480        }
2481
2482        if (lrui >= mLruProcessActivityStart) {
2483            // Don't want to touch dependent processes that are hosting activities.
2484            return index;
2485        }
2486
2487        mLruProcesses.remove(lrui);
2488        if (index > 0) {
2489            index--;
2490        }
2491        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2492                + " in LRU list: " + app);
2493        mLruProcesses.add(index, app);
2494        return index;
2495    }
2496
2497    final void removeLruProcessLocked(ProcessRecord app) {
2498        int lrui = mLruProcesses.lastIndexOf(app);
2499        if (lrui >= 0) {
2500            if (lrui <= mLruProcessActivityStart) {
2501                mLruProcessActivityStart--;
2502            }
2503            if (lrui <= mLruProcessServiceStart) {
2504                mLruProcessServiceStart--;
2505            }
2506            mLruProcesses.remove(lrui);
2507        }
2508    }
2509
2510    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2511            ProcessRecord client) {
2512        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2513                || app.treatLikeActivity;
2514        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2515        if (!activityChange && hasActivity) {
2516            // The process has activities, so we are only allowing activity-based adjustments
2517            // to move it.  It should be kept in the front of the list with other
2518            // processes that have activities, and we don't want those to change their
2519            // order except due to activity operations.
2520            return;
2521        }
2522
2523        mLruSeq++;
2524        final long now = SystemClock.uptimeMillis();
2525        app.lastActivityTime = now;
2526
2527        // First a quick reject: if the app is already at the position we will
2528        // put it, then there is nothing to do.
2529        if (hasActivity) {
2530            final int N = mLruProcesses.size();
2531            if (N > 0 && mLruProcesses.get(N-1) == app) {
2532                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2533                return;
2534            }
2535        } else {
2536            if (mLruProcessServiceStart > 0
2537                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2538                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2539                return;
2540            }
2541        }
2542
2543        int lrui = mLruProcesses.lastIndexOf(app);
2544
2545        if (app.persistent && lrui >= 0) {
2546            // We don't care about the position of persistent processes, as long as
2547            // they are in the list.
2548            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2549            return;
2550        }
2551
2552        /* In progress: compute new position first, so we can avoid doing work
2553           if the process is not actually going to move.  Not yet working.
2554        int addIndex;
2555        int nextIndex;
2556        boolean inActivity = false, inService = false;
2557        if (hasActivity) {
2558            // Process has activities, put it at the very tipsy-top.
2559            addIndex = mLruProcesses.size();
2560            nextIndex = mLruProcessServiceStart;
2561            inActivity = true;
2562        } else if (hasService) {
2563            // Process has services, put it at the top of the service list.
2564            addIndex = mLruProcessActivityStart;
2565            nextIndex = mLruProcessServiceStart;
2566            inActivity = true;
2567            inService = true;
2568        } else  {
2569            // Process not otherwise of interest, it goes to the top of the non-service area.
2570            addIndex = mLruProcessServiceStart;
2571            if (client != null) {
2572                int clientIndex = mLruProcesses.lastIndexOf(client);
2573                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2574                        + app);
2575                if (clientIndex >= 0 && addIndex > clientIndex) {
2576                    addIndex = clientIndex;
2577                }
2578            }
2579            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2580        }
2581
2582        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2583                + mLruProcessActivityStart + "): " + app);
2584        */
2585
2586        if (lrui >= 0) {
2587            if (lrui < mLruProcessActivityStart) {
2588                mLruProcessActivityStart--;
2589            }
2590            if (lrui < mLruProcessServiceStart) {
2591                mLruProcessServiceStart--;
2592            }
2593            /*
2594            if (addIndex > lrui) {
2595                addIndex--;
2596            }
2597            if (nextIndex > lrui) {
2598                nextIndex--;
2599            }
2600            */
2601            mLruProcesses.remove(lrui);
2602        }
2603
2604        /*
2605        mLruProcesses.add(addIndex, app);
2606        if (inActivity) {
2607            mLruProcessActivityStart++;
2608        }
2609        if (inService) {
2610            mLruProcessActivityStart++;
2611        }
2612        */
2613
2614        int nextIndex;
2615        if (hasActivity) {
2616            final int N = mLruProcesses.size();
2617            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2618                // Process doesn't have activities, but has clients with
2619                // activities...  move it up, but one below the top (the top
2620                // should always have a real activity).
2621                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2622                mLruProcesses.add(N-1, app);
2623                // To keep it from spamming the LRU list (by making a bunch of clients),
2624                // we will push down any other entries owned by the app.
2625                final int uid = app.info.uid;
2626                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2627                    ProcessRecord subProc = mLruProcesses.get(i);
2628                    if (subProc.info.uid == uid) {
2629                        // We want to push this one down the list.  If the process after
2630                        // it is for the same uid, however, don't do so, because we don't
2631                        // want them internally to be re-ordered.
2632                        if (mLruProcesses.get(i-1).info.uid != uid) {
2633                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2634                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2635                            ProcessRecord tmp = mLruProcesses.get(i);
2636                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2637                            mLruProcesses.set(i-1, tmp);
2638                            i--;
2639                        }
2640                    } else {
2641                        // A gap, we can stop here.
2642                        break;
2643                    }
2644                }
2645            } else {
2646                // Process has activities, put it at the very tipsy-top.
2647                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2648                mLruProcesses.add(app);
2649            }
2650            nextIndex = mLruProcessServiceStart;
2651        } else if (hasService) {
2652            // Process has services, put it at the top of the service list.
2653            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2654            mLruProcesses.add(mLruProcessActivityStart, app);
2655            nextIndex = mLruProcessServiceStart;
2656            mLruProcessActivityStart++;
2657        } else  {
2658            // Process not otherwise of interest, it goes to the top of the non-service area.
2659            int index = mLruProcessServiceStart;
2660            if (client != null) {
2661                // If there is a client, don't allow the process to be moved up higher
2662                // in the list than that client.
2663                int clientIndex = mLruProcesses.lastIndexOf(client);
2664                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2665                        + " when updating " + app);
2666                if (clientIndex <= lrui) {
2667                    // Don't allow the client index restriction to push it down farther in the
2668                    // list than it already is.
2669                    clientIndex = lrui;
2670                }
2671                if (clientIndex >= 0 && index > clientIndex) {
2672                    index = clientIndex;
2673                }
2674            }
2675            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2676            mLruProcesses.add(index, app);
2677            nextIndex = index-1;
2678            mLruProcessActivityStart++;
2679            mLruProcessServiceStart++;
2680        }
2681
2682        // If the app is currently using a content provider or service,
2683        // bump those processes as well.
2684        for (int j=app.connections.size()-1; j>=0; j--) {
2685            ConnectionRecord cr = app.connections.valueAt(j);
2686            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2687                    && cr.binding.service.app != null
2688                    && cr.binding.service.app.lruSeq != mLruSeq
2689                    && !cr.binding.service.app.persistent) {
2690                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2691                        "service connection", cr, app);
2692            }
2693        }
2694        for (int j=app.conProviders.size()-1; j>=0; j--) {
2695            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2696            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2697                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2698                        "provider reference", cpr, app);
2699            }
2700        }
2701    }
2702
2703    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2704        if (uid == Process.SYSTEM_UID) {
2705            // The system gets to run in any process.  If there are multiple
2706            // processes with the same uid, just pick the first (this
2707            // should never happen).
2708            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2709            if (procs == null) return null;
2710            final int N = procs.size();
2711            for (int i = 0; i < N; i++) {
2712                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2713            }
2714        }
2715        ProcessRecord proc = mProcessNames.get(processName, uid);
2716        if (false && proc != null && !keepIfLarge
2717                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2718                && proc.lastCachedPss >= 4000) {
2719            // Turn this condition on to cause killing to happen regularly, for testing.
2720            if (proc.baseProcessTracker != null) {
2721                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2722            }
2723            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2724                    + "k from cached");
2725        } else if (proc != null && !keepIfLarge
2726                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2727                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2728            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2729            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2730                if (proc.baseProcessTracker != null) {
2731                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2732                }
2733                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2734                        + "k from cached");
2735            }
2736        }
2737        return proc;
2738    }
2739
2740    void ensurePackageDexOpt(String packageName) {
2741        IPackageManager pm = AppGlobals.getPackageManager();
2742        try {
2743            if (pm.performDexOpt(packageName)) {
2744                mDidDexOpt = true;
2745            }
2746        } catch (RemoteException e) {
2747        }
2748    }
2749
2750    boolean isNextTransitionForward() {
2751        int transit = mWindowManager.getPendingAppTransition();
2752        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2753                || transit == AppTransition.TRANSIT_TASK_OPEN
2754                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2755    }
2756
2757    final ProcessRecord startProcessLocked(String processName,
2758            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2759            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2760            boolean isolated, boolean keepIfLarge) {
2761        ProcessRecord app;
2762        if (!isolated) {
2763            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2764        } else {
2765            // If this is an isolated process, it can't re-use an existing process.
2766            app = null;
2767        }
2768        // We don't have to do anything more if:
2769        // (1) There is an existing application record; and
2770        // (2) The caller doesn't think it is dead, OR there is no thread
2771        //     object attached to it so we know it couldn't have crashed; and
2772        // (3) There is a pid assigned to it, so it is either starting or
2773        //     already running.
2774        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2775                + " app=" + app + " knownToBeDead=" + knownToBeDead
2776                + " thread=" + (app != null ? app.thread : null)
2777                + " pid=" + (app != null ? app.pid : -1));
2778        if (app != null && app.pid > 0) {
2779            if (!knownToBeDead || app.thread == null) {
2780                // We already have the app running, or are waiting for it to
2781                // come up (we have a pid but not yet its thread), so keep it.
2782                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2783                // If this is a new package in the process, add the package to the list
2784                app.addPackage(info.packageName, mProcessStats);
2785                return app;
2786            }
2787
2788            // An application record is attached to a previous process,
2789            // clean it up now.
2790            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2791            handleAppDiedLocked(app, true, true);
2792        }
2793
2794        String hostingNameStr = hostingName != null
2795                ? hostingName.flattenToShortString() : null;
2796
2797        if (!isolated) {
2798            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2799                // If we are in the background, then check to see if this process
2800                // is bad.  If so, we will just silently fail.
2801                if (mBadProcesses.get(info.processName, info.uid) != null) {
2802                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2803                            + "/" + info.processName);
2804                    return null;
2805                }
2806            } else {
2807                // When the user is explicitly starting a process, then clear its
2808                // crash count so that we won't make it bad until they see at
2809                // least one crash dialog again, and make the process good again
2810                // if it had been bad.
2811                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2812                        + "/" + info.processName);
2813                mProcessCrashTimes.remove(info.processName, info.uid);
2814                if (mBadProcesses.get(info.processName, info.uid) != null) {
2815                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2816                            UserHandle.getUserId(info.uid), info.uid,
2817                            info.processName);
2818                    mBadProcesses.remove(info.processName, info.uid);
2819                    if (app != null) {
2820                        app.bad = false;
2821                    }
2822                }
2823            }
2824        }
2825
2826        if (app == null) {
2827            app = newProcessRecordLocked(info, processName, isolated);
2828            if (app == null) {
2829                Slog.w(TAG, "Failed making new process record for "
2830                        + processName + "/" + info.uid + " isolated=" + isolated);
2831                return null;
2832            }
2833            mProcessNames.put(processName, app.uid, app);
2834            if (isolated) {
2835                mIsolatedProcesses.put(app.uid, app);
2836            }
2837        } else {
2838            // If this is a new package in the process, add the package to the list
2839            app.addPackage(info.packageName, mProcessStats);
2840        }
2841
2842        // If the system is not ready yet, then hold off on starting this
2843        // process until it is.
2844        if (!mProcessesReady
2845                && !isAllowedWhileBooting(info)
2846                && !allowWhileBooting) {
2847            if (!mProcessesOnHold.contains(app)) {
2848                mProcessesOnHold.add(app);
2849            }
2850            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2851            return app;
2852        }
2853
2854        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2855        return (app.pid != 0) ? app : null;
2856    }
2857
2858    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2859        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2860    }
2861
2862    private final void startProcessLocked(ProcessRecord app,
2863            String hostingType, String hostingNameStr, String abiOverride) {
2864        if (app.pid > 0 && app.pid != MY_PID) {
2865            synchronized (mPidsSelfLocked) {
2866                mPidsSelfLocked.remove(app.pid);
2867                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2868            }
2869            app.setPid(0);
2870        }
2871
2872        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2873                "startProcessLocked removing on hold: " + app);
2874        mProcessesOnHold.remove(app);
2875
2876        updateCpuStats();
2877
2878        try {
2879            int uid = app.uid;
2880
2881            int[] gids = null;
2882            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2883            if (!app.isolated) {
2884                int[] permGids = null;
2885                try {
2886                    final PackageManager pm = mContext.getPackageManager();
2887                    permGids = pm.getPackageGids(app.info.packageName);
2888
2889                    if (Environment.isExternalStorageEmulated()) {
2890                        if (pm.checkPermission(
2891                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2892                                app.info.packageName) == PERMISSION_GRANTED) {
2893                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2894                        } else {
2895                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2896                        }
2897                    }
2898                } catch (PackageManager.NameNotFoundException e) {
2899                    Slog.w(TAG, "Unable to retrieve gids", e);
2900                }
2901
2902                /*
2903                 * Add shared application and profile GIDs so applications can share some
2904                 * resources like shared libraries and access user-wide resources
2905                 */
2906                if (permGids == null) {
2907                    gids = new int[2];
2908                } else {
2909                    gids = new int[permGids.length + 2];
2910                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2911                }
2912                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2913                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2914            }
2915            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2916                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2917                        && mTopComponent != null
2918                        && app.processName.equals(mTopComponent.getPackageName())) {
2919                    uid = 0;
2920                }
2921                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2922                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2923                    uid = 0;
2924                }
2925            }
2926            int debugFlags = 0;
2927            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2928                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2929                // Also turn on CheckJNI for debuggable apps. It's quite
2930                // awkward to turn on otherwise.
2931                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2932            }
2933            // Run the app in safe mode if its manifest requests so or the
2934            // system is booted in safe mode.
2935            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2936                mSafeMode == true) {
2937                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2938            }
2939            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2940                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2941            }
2942            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2943                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2944            }
2945            if ("1".equals(SystemProperties.get("debug.assert"))) {
2946                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2947            }
2948
2949            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2950            if (requiredAbi == null) {
2951                requiredAbi = Build.SUPPORTED_ABIS[0];
2952            }
2953
2954            // Start the process.  It will either succeed and return a result containing
2955            // the PID of the new process, or else throw a RuntimeException.
2956            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2957                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2958                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2959
2960            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2961            synchronized (bs) {
2962                if (bs.isOnBattery()) {
2963                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2964                }
2965            }
2966
2967            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2968                    UserHandle.getUserId(uid), startResult.pid, uid,
2969                    app.processName, hostingType,
2970                    hostingNameStr != null ? hostingNameStr : "");
2971
2972            if (app.persistent) {
2973                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2974            }
2975
2976            StringBuilder buf = mStringBuilder;
2977            buf.setLength(0);
2978            buf.append("Start proc ");
2979            buf.append(app.processName);
2980            buf.append(" for ");
2981            buf.append(hostingType);
2982            if (hostingNameStr != null) {
2983                buf.append(" ");
2984                buf.append(hostingNameStr);
2985            }
2986            buf.append(": pid=");
2987            buf.append(startResult.pid);
2988            buf.append(" uid=");
2989            buf.append(uid);
2990            buf.append(" gids={");
2991            if (gids != null) {
2992                for (int gi=0; gi<gids.length; gi++) {
2993                    if (gi != 0) buf.append(", ");
2994                    buf.append(gids[gi]);
2995
2996                }
2997            }
2998            buf.append("}");
2999            if (requiredAbi != null) {
3000                buf.append(" abi=");
3001                buf.append(requiredAbi);
3002            }
3003            Slog.i(TAG, buf.toString());
3004            app.setPid(startResult.pid);
3005            app.usingWrapper = startResult.usingWrapper;
3006            app.removed = false;
3007            synchronized (mPidsSelfLocked) {
3008                this.mPidsSelfLocked.put(startResult.pid, app);
3009                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3010                msg.obj = app;
3011                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3012                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3013            }
3014            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3015                    app.processName, app.info.uid);
3016            if (app.isolated) {
3017                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3018            }
3019        } catch (RuntimeException e) {
3020            // XXX do better error recovery.
3021            app.setPid(0);
3022            Slog.e(TAG, "Failure starting process " + app.processName, e);
3023        }
3024    }
3025
3026    void updateUsageStats(ActivityRecord component, boolean resumed) {
3027        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3028        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3029        if (resumed) {
3030            mUsageStatsService.noteResumeComponent(component.realActivity);
3031            synchronized (stats) {
3032                stats.noteActivityResumedLocked(component.app.uid);
3033            }
3034        } else {
3035            mUsageStatsService.notePauseComponent(component.realActivity);
3036            synchronized (stats) {
3037                stats.noteActivityPausedLocked(component.app.uid);
3038            }
3039        }
3040    }
3041
3042    Intent getHomeIntent() {
3043        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3044        intent.setComponent(mTopComponent);
3045        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3046            intent.addCategory(Intent.CATEGORY_HOME);
3047        }
3048        return intent;
3049    }
3050
3051    boolean startHomeActivityLocked(int userId) {
3052        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3053                && mTopAction == null) {
3054            // We are running in factory test mode, but unable to find
3055            // the factory test app, so just sit around displaying the
3056            // error message and don't try to start anything.
3057            return false;
3058        }
3059        Intent intent = getHomeIntent();
3060        ActivityInfo aInfo =
3061            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3062        if (aInfo != null) {
3063            intent.setComponent(new ComponentName(
3064                    aInfo.applicationInfo.packageName, aInfo.name));
3065            // Don't do this if the home app is currently being
3066            // instrumented.
3067            aInfo = new ActivityInfo(aInfo);
3068            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3069            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3070                    aInfo.applicationInfo.uid, true);
3071            if (app == null || app.instrumentationClass == null) {
3072                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3073                mStackSupervisor.startHomeActivity(intent, aInfo);
3074            }
3075        }
3076
3077        return true;
3078    }
3079
3080    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3081        ActivityInfo ai = null;
3082        ComponentName comp = intent.getComponent();
3083        try {
3084            if (comp != null) {
3085                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3086            } else {
3087                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3088                        intent,
3089                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3090                            flags, userId);
3091
3092                if (info != null) {
3093                    ai = info.activityInfo;
3094                }
3095            }
3096        } catch (RemoteException e) {
3097            // ignore
3098        }
3099
3100        return ai;
3101    }
3102
3103    /**
3104     * Starts the "new version setup screen" if appropriate.
3105     */
3106    void startSetupActivityLocked() {
3107        // Only do this once per boot.
3108        if (mCheckedForSetup) {
3109            return;
3110        }
3111
3112        // We will show this screen if the current one is a different
3113        // version than the last one shown, and we are not running in
3114        // low-level factory test mode.
3115        final ContentResolver resolver = mContext.getContentResolver();
3116        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3117                Settings.Global.getInt(resolver,
3118                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3119            mCheckedForSetup = true;
3120
3121            // See if we should be showing the platform update setup UI.
3122            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3123            List<ResolveInfo> ris = mContext.getPackageManager()
3124                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3125
3126            // We don't allow third party apps to replace this.
3127            ResolveInfo ri = null;
3128            for (int i=0; ris != null && i<ris.size(); i++) {
3129                if ((ris.get(i).activityInfo.applicationInfo.flags
3130                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3131                    ri = ris.get(i);
3132                    break;
3133                }
3134            }
3135
3136            if (ri != null) {
3137                String vers = ri.activityInfo.metaData != null
3138                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3139                        : null;
3140                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3141                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3142                            Intent.METADATA_SETUP_VERSION);
3143                }
3144                String lastVers = Settings.Secure.getString(
3145                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3146                if (vers != null && !vers.equals(lastVers)) {
3147                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3148                    intent.setComponent(new ComponentName(
3149                            ri.activityInfo.packageName, ri.activityInfo.name));
3150                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3151                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3152                }
3153            }
3154        }
3155    }
3156
3157    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3158        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3159    }
3160
3161    void enforceNotIsolatedCaller(String caller) {
3162        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3163            throw new SecurityException("Isolated process not allowed to call " + caller);
3164        }
3165    }
3166
3167    @Override
3168    public int getFrontActivityScreenCompatMode() {
3169        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3170        synchronized (this) {
3171            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3172        }
3173    }
3174
3175    @Override
3176    public void setFrontActivityScreenCompatMode(int mode) {
3177        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3178                "setFrontActivityScreenCompatMode");
3179        synchronized (this) {
3180            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3181        }
3182    }
3183
3184    @Override
3185    public int getPackageScreenCompatMode(String packageName) {
3186        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3187        synchronized (this) {
3188            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3189        }
3190    }
3191
3192    @Override
3193    public void setPackageScreenCompatMode(String packageName, int mode) {
3194        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3195                "setPackageScreenCompatMode");
3196        synchronized (this) {
3197            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3198        }
3199    }
3200
3201    @Override
3202    public boolean getPackageAskScreenCompat(String packageName) {
3203        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3204        synchronized (this) {
3205            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3206        }
3207    }
3208
3209    @Override
3210    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3211        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3212                "setPackageAskScreenCompat");
3213        synchronized (this) {
3214            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3215        }
3216    }
3217
3218    private void dispatchProcessesChanged() {
3219        int N;
3220        synchronized (this) {
3221            N = mPendingProcessChanges.size();
3222            if (mActiveProcessChanges.length < N) {
3223                mActiveProcessChanges = new ProcessChangeItem[N];
3224            }
3225            mPendingProcessChanges.toArray(mActiveProcessChanges);
3226            mAvailProcessChanges.addAll(mPendingProcessChanges);
3227            mPendingProcessChanges.clear();
3228            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3229        }
3230
3231        int i = mProcessObservers.beginBroadcast();
3232        while (i > 0) {
3233            i--;
3234            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3235            if (observer != null) {
3236                try {
3237                    for (int j=0; j<N; j++) {
3238                        ProcessChangeItem item = mActiveProcessChanges[j];
3239                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3240                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3241                                    + item.pid + " uid=" + item.uid + ": "
3242                                    + item.foregroundActivities);
3243                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3244                                    item.foregroundActivities);
3245                        }
3246                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3247                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3248                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3249                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3250                        }
3251                    }
3252                } catch (RemoteException e) {
3253                }
3254            }
3255        }
3256        mProcessObservers.finishBroadcast();
3257    }
3258
3259    private void dispatchProcessDied(int pid, int uid) {
3260        int i = mProcessObservers.beginBroadcast();
3261        while (i > 0) {
3262            i--;
3263            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3264            if (observer != null) {
3265                try {
3266                    observer.onProcessDied(pid, uid);
3267                } catch (RemoteException e) {
3268                }
3269            }
3270        }
3271        mProcessObservers.finishBroadcast();
3272    }
3273
3274    final void doPendingActivityLaunchesLocked(boolean doResume) {
3275        final int N = mPendingActivityLaunches.size();
3276        if (N <= 0) {
3277            return;
3278        }
3279        for (int i=0; i<N; i++) {
3280            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3281            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3282                    doResume && i == (N-1), null);
3283        }
3284        mPendingActivityLaunches.clear();
3285    }
3286
3287    @Override
3288    public final int startActivity(IApplicationThread caller, String callingPackage,
3289            Intent intent, String resolvedType, IBinder resultTo,
3290            String resultWho, int requestCode, int startFlags,
3291            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3292        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3293                resultWho, requestCode,
3294                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3295    }
3296
3297    @Override
3298    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3299            Intent intent, String resolvedType, IBinder resultTo,
3300            String resultWho, int requestCode, int startFlags,
3301            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3302        enforceNotIsolatedCaller("startActivity");
3303        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3304                false, true, "startActivity", null);
3305        // TODO: Switch to user app stacks here.
3306        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3307                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3308                null, null, options, userId, null);
3309    }
3310
3311    @Override
3312    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3313            Intent intent, String resolvedType, IBinder resultTo,
3314            String resultWho, int requestCode, int startFlags, String profileFile,
3315            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3316        enforceNotIsolatedCaller("startActivityAndWait");
3317        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3318                false, true, "startActivityAndWait", null);
3319        WaitResult res = new WaitResult();
3320        // TODO: Switch to user app stacks here.
3321        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3322                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3323                res, null, options, UserHandle.getCallingUserId(), null);
3324        return res;
3325    }
3326
3327    @Override
3328    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3329            Intent intent, String resolvedType, IBinder resultTo,
3330            String resultWho, int requestCode, int startFlags, Configuration config,
3331            Bundle options, int userId) {
3332        enforceNotIsolatedCaller("startActivityWithConfig");
3333        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3334                false, true, "startActivityWithConfig", null);
3335        // TODO: Switch to user app stacks here.
3336        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3337                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3338                null, null, null, config, options, userId, null);
3339        return ret;
3340    }
3341
3342    @Override
3343    public int startActivityIntentSender(IApplicationThread caller,
3344            IntentSender intent, Intent fillInIntent, String resolvedType,
3345            IBinder resultTo, String resultWho, int requestCode,
3346            int flagsMask, int flagsValues, Bundle options) {
3347        enforceNotIsolatedCaller("startActivityIntentSender");
3348        // Refuse possible leaked file descriptors
3349        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3350            throw new IllegalArgumentException("File descriptors passed in Intent");
3351        }
3352
3353        IIntentSender sender = intent.getTarget();
3354        if (!(sender instanceof PendingIntentRecord)) {
3355            throw new IllegalArgumentException("Bad PendingIntent object");
3356        }
3357
3358        PendingIntentRecord pir = (PendingIntentRecord)sender;
3359
3360        synchronized (this) {
3361            // If this is coming from the currently resumed activity, it is
3362            // effectively saying that app switches are allowed at this point.
3363            final ActivityStack stack = getFocusedStack();
3364            if (stack.mResumedActivity != null &&
3365                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3366                mAppSwitchesAllowedTime = 0;
3367            }
3368        }
3369        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3370                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3371        return ret;
3372    }
3373
3374    @Override
3375    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3376            Intent intent, String resolvedType, IVoiceInteractionSession session,
3377            IVoiceInteractor interactor, int startFlags, String profileFile,
3378            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3379        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3380                != PackageManager.PERMISSION_GRANTED) {
3381            String msg = "Permission Denial: startVoiceActivity() from pid="
3382                    + Binder.getCallingPid()
3383                    + ", uid=" + Binder.getCallingUid()
3384                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3385            Slog.w(TAG, msg);
3386            throw new SecurityException(msg);
3387        }
3388        if (session == null || interactor == null) {
3389            throw new NullPointerException("null session or interactor");
3390        }
3391        userId = handleIncomingUser(callingPid, callingUid, userId,
3392                false, true, "startVoiceActivity", null);
3393        // TODO: Switch to user app stacks here.
3394        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3395                resolvedType, session, interactor, null, null, 0, startFlags,
3396                profileFile, profileFd, null, null, options, userId, null);
3397    }
3398
3399    @Override
3400    public boolean startNextMatchingActivity(IBinder callingActivity,
3401            Intent intent, Bundle options) {
3402        // Refuse possible leaked file descriptors
3403        if (intent != null && intent.hasFileDescriptors() == true) {
3404            throw new IllegalArgumentException("File descriptors passed in Intent");
3405        }
3406
3407        synchronized (this) {
3408            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3409            if (r == null) {
3410                ActivityOptions.abort(options);
3411                return false;
3412            }
3413            if (r.app == null || r.app.thread == null) {
3414                // The caller is not running...  d'oh!
3415                ActivityOptions.abort(options);
3416                return false;
3417            }
3418            intent = new Intent(intent);
3419            // The caller is not allowed to change the data.
3420            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3421            // And we are resetting to find the next component...
3422            intent.setComponent(null);
3423
3424            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3425
3426            ActivityInfo aInfo = null;
3427            try {
3428                List<ResolveInfo> resolves =
3429                    AppGlobals.getPackageManager().queryIntentActivities(
3430                            intent, r.resolvedType,
3431                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3432                            UserHandle.getCallingUserId());
3433
3434                // Look for the original activity in the list...
3435                final int N = resolves != null ? resolves.size() : 0;
3436                for (int i=0; i<N; i++) {
3437                    ResolveInfo rInfo = resolves.get(i);
3438                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3439                            && rInfo.activityInfo.name.equals(r.info.name)) {
3440                        // We found the current one...  the next matching is
3441                        // after it.
3442                        i++;
3443                        if (i<N) {
3444                            aInfo = resolves.get(i).activityInfo;
3445                        }
3446                        if (debug) {
3447                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3448                                    + "/" + r.info.name);
3449                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3450                                    + "/" + aInfo.name);
3451                        }
3452                        break;
3453                    }
3454                }
3455            } catch (RemoteException e) {
3456            }
3457
3458            if (aInfo == null) {
3459                // Nobody who is next!
3460                ActivityOptions.abort(options);
3461                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3462                return false;
3463            }
3464
3465            intent.setComponent(new ComponentName(
3466                    aInfo.applicationInfo.packageName, aInfo.name));
3467            intent.setFlags(intent.getFlags()&~(
3468                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3469                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3470                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3471                    Intent.FLAG_ACTIVITY_NEW_TASK));
3472
3473            // Okay now we need to start the new activity, replacing the
3474            // currently running activity.  This is a little tricky because
3475            // we want to start the new one as if the current one is finished,
3476            // but not finish the current one first so that there is no flicker.
3477            // And thus...
3478            final boolean wasFinishing = r.finishing;
3479            r.finishing = true;
3480
3481            // Propagate reply information over to the new activity.
3482            final ActivityRecord resultTo = r.resultTo;
3483            final String resultWho = r.resultWho;
3484            final int requestCode = r.requestCode;
3485            r.resultTo = null;
3486            if (resultTo != null) {
3487                resultTo.removeResultsLocked(r, resultWho, requestCode);
3488            }
3489
3490            final long origId = Binder.clearCallingIdentity();
3491            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3492                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3493                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3494                    options, false, null, null);
3495            Binder.restoreCallingIdentity(origId);
3496
3497            r.finishing = wasFinishing;
3498            if (res != ActivityManager.START_SUCCESS) {
3499                return false;
3500            }
3501            return true;
3502        }
3503    }
3504
3505    final int startActivityInPackage(int uid, String callingPackage,
3506            Intent intent, String resolvedType, IBinder resultTo,
3507            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3508                    IActivityContainer container) {
3509
3510        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3511                false, true, "startActivityInPackage", null);
3512
3513        // TODO: Switch to user app stacks here.
3514        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3515                null, null, resultTo, resultWho, requestCode, startFlags,
3516                null, null, null, null, options, userId, container);
3517        return ret;
3518    }
3519
3520    @Override
3521    public final int startActivities(IApplicationThread caller, String callingPackage,
3522            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3523            int userId) {
3524        enforceNotIsolatedCaller("startActivities");
3525        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3526                false, true, "startActivity", null);
3527        // TODO: Switch to user app stacks here.
3528        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3529                resolvedTypes, resultTo, options, userId);
3530        return ret;
3531    }
3532
3533    final int startActivitiesInPackage(int uid, String callingPackage,
3534            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3535            Bundle options, int userId) {
3536
3537        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3538                false, true, "startActivityInPackage", null);
3539        // TODO: Switch to user app stacks here.
3540        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3541                resultTo, options, userId);
3542        return ret;
3543    }
3544
3545    final void addRecentTaskLocked(TaskRecord task) {
3546        int N = mRecentTasks.size();
3547        // Quick case: check if the top-most recent task is the same.
3548        if (N > 0 && mRecentTasks.get(0) == task) {
3549            return;
3550        }
3551        // Another quick case: never add voice sessions.
3552        if (task.voiceSession != null) {
3553            return;
3554        }
3555        // Remove any existing entries that are the same kind of task.
3556        final Intent intent = task.intent;
3557        final boolean document = intent != null && intent.isDocument();
3558        final ComponentName comp = intent.getComponent();
3559
3560        int maxRecents = task.maxRecents - 1;
3561        for (int i=0; i<N; i++) {
3562            TaskRecord tr = mRecentTasks.get(i);
3563            if (task != tr) {
3564                if (task.userId != tr.userId) {
3565                    continue;
3566                }
3567                final Intent trIntent = tr.intent;
3568                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3569                    (intent == null || !intent.filterEquals(trIntent))) {
3570                    continue;
3571                }
3572                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3573                if (document && trIsDocument) {
3574                    // These are the same document activity (not necessarily the same doc).
3575                    if (maxRecents > 0) {
3576                        --maxRecents;
3577                        continue;
3578                    }
3579                    // Hit the maximum number of documents for this task. Fall through
3580                    // and remove this document from recents.
3581                } else if (document || trIsDocument) {
3582                    // Only one of these is a document. Not the droid we're looking for.
3583                    continue;
3584                }
3585            }
3586
3587            // Either task and tr are the same or, their affinities match or their intents match
3588            // and neither of them is a document, or they are documents using the same activity
3589            // and their maxRecents has been reached.
3590            tr.disposeThumbnail();
3591            mRecentTasks.remove(i);
3592            i--;
3593            N--;
3594            if (task.intent == null) {
3595                // If the new recent task we are adding is not fully
3596                // specified, then replace it with the existing recent task.
3597                task = tr;
3598            }
3599            mTaskPersister.notify(tr, false);
3600        }
3601        if (N >= MAX_RECENT_TASKS) {
3602            mRecentTasks.remove(N-1).disposeThumbnail();
3603        }
3604        mRecentTasks.add(0, task);
3605    }
3606
3607    @Override
3608    public void reportActivityFullyDrawn(IBinder token) {
3609        synchronized (this) {
3610            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3611            if (r == null) {
3612                return;
3613            }
3614            r.reportFullyDrawnLocked();
3615        }
3616    }
3617
3618    @Override
3619    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3620        synchronized (this) {
3621            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3622            if (r == null) {
3623                return;
3624            }
3625            final long origId = Binder.clearCallingIdentity();
3626            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3627            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3628                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3629            if (config != null) {
3630                r.frozenBeforeDestroy = true;
3631                if (!updateConfigurationLocked(config, r, false, false)) {
3632                    mStackSupervisor.resumeTopActivitiesLocked();
3633                }
3634            }
3635            Binder.restoreCallingIdentity(origId);
3636        }
3637    }
3638
3639    @Override
3640    public int getRequestedOrientation(IBinder token) {
3641        synchronized (this) {
3642            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3643            if (r == null) {
3644                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3645            }
3646            return mWindowManager.getAppOrientation(r.appToken);
3647        }
3648    }
3649
3650    /**
3651     * This is the internal entry point for handling Activity.finish().
3652     *
3653     * @param token The Binder token referencing the Activity we want to finish.
3654     * @param resultCode Result code, if any, from this Activity.
3655     * @param resultData Result data (Intent), if any, from this Activity.
3656     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3657     *            the root Activity in the task.
3658     *
3659     * @return Returns true if the activity successfully finished, or false if it is still running.
3660     */
3661    @Override
3662    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3663            boolean finishTask) {
3664        // Refuse possible leaked file descriptors
3665        if (resultData != null && resultData.hasFileDescriptors() == true) {
3666            throw new IllegalArgumentException("File descriptors passed in Intent");
3667        }
3668
3669        synchronized(this) {
3670            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3671            if (r == null) {
3672                return true;
3673            }
3674            // Keep track of the root activity of the task before we finish it
3675            TaskRecord tr = r.task;
3676            ActivityRecord rootR = tr.getRootActivity();
3677            // Do not allow task to finish in Lock Task mode.
3678            if (tr == mStackSupervisor.mLockTaskModeTask) {
3679                if (rootR == r) {
3680                    return false;
3681                }
3682            }
3683            if (mController != null) {
3684                // Find the first activity that is not finishing.
3685                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3686                if (next != null) {
3687                    // ask watcher if this is allowed
3688                    boolean resumeOK = true;
3689                    try {
3690                        resumeOK = mController.activityResuming(next.packageName);
3691                    } catch (RemoteException e) {
3692                        mController = null;
3693                        Watchdog.getInstance().setActivityController(null);
3694                    }
3695
3696                    if (!resumeOK) {
3697                        return false;
3698                    }
3699                }
3700            }
3701            final long origId = Binder.clearCallingIdentity();
3702            try {
3703                boolean res;
3704                if (finishTask && r == rootR) {
3705                    // If requested, remove the task that is associated to this activity only if it
3706                    // was the root activity in the task.  The result code and data is ignored because
3707                    // we don't support returning them across task boundaries.
3708                    res = removeTaskByIdLocked(tr.taskId, 0);
3709                } else {
3710                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3711                            resultData, "app-request", true);
3712                }
3713                return res;
3714            } finally {
3715                Binder.restoreCallingIdentity(origId);
3716            }
3717        }
3718    }
3719
3720    @Override
3721    public final void finishHeavyWeightApp() {
3722        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3723                != PackageManager.PERMISSION_GRANTED) {
3724            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3725                    + Binder.getCallingPid()
3726                    + ", uid=" + Binder.getCallingUid()
3727                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3728            Slog.w(TAG, msg);
3729            throw new SecurityException(msg);
3730        }
3731
3732        synchronized(this) {
3733            if (mHeavyWeightProcess == null) {
3734                return;
3735            }
3736
3737            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3738                    mHeavyWeightProcess.activities);
3739            for (int i=0; i<activities.size(); i++) {
3740                ActivityRecord r = activities.get(i);
3741                if (!r.finishing) {
3742                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3743                            null, "finish-heavy", true);
3744                }
3745            }
3746
3747            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3748                    mHeavyWeightProcess.userId, 0));
3749            mHeavyWeightProcess = null;
3750        }
3751    }
3752
3753    @Override
3754    public void crashApplication(int uid, int initialPid, String packageName,
3755            String message) {
3756        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3757                != PackageManager.PERMISSION_GRANTED) {
3758            String msg = "Permission Denial: crashApplication() from pid="
3759                    + Binder.getCallingPid()
3760                    + ", uid=" + Binder.getCallingUid()
3761                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3762            Slog.w(TAG, msg);
3763            throw new SecurityException(msg);
3764        }
3765
3766        synchronized(this) {
3767            ProcessRecord proc = null;
3768
3769            // Figure out which process to kill.  We don't trust that initialPid
3770            // still has any relation to current pids, so must scan through the
3771            // list.
3772            synchronized (mPidsSelfLocked) {
3773                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3774                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3775                    if (p.uid != uid) {
3776                        continue;
3777                    }
3778                    if (p.pid == initialPid) {
3779                        proc = p;
3780                        break;
3781                    }
3782                    if (p.pkgList.containsKey(packageName)) {
3783                        proc = p;
3784                    }
3785                }
3786            }
3787
3788            if (proc == null) {
3789                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3790                        + " initialPid=" + initialPid
3791                        + " packageName=" + packageName);
3792                return;
3793            }
3794
3795            if (proc.thread != null) {
3796                if (proc.pid == Process.myPid()) {
3797                    Log.w(TAG, "crashApplication: trying to crash self!");
3798                    return;
3799                }
3800                long ident = Binder.clearCallingIdentity();
3801                try {
3802                    proc.thread.scheduleCrash(message);
3803                } catch (RemoteException e) {
3804                }
3805                Binder.restoreCallingIdentity(ident);
3806            }
3807        }
3808    }
3809
3810    @Override
3811    public final void finishSubActivity(IBinder token, String resultWho,
3812            int requestCode) {
3813        synchronized(this) {
3814            final long origId = Binder.clearCallingIdentity();
3815            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3816            if (r != null) {
3817                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3818            }
3819            Binder.restoreCallingIdentity(origId);
3820        }
3821    }
3822
3823    @Override
3824    public boolean finishActivityAffinity(IBinder token) {
3825        synchronized(this) {
3826            final long origId = Binder.clearCallingIdentity();
3827            try {
3828                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3829
3830                ActivityRecord rootR = r.task.getRootActivity();
3831                // Do not allow task to finish in Lock Task mode.
3832                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3833                    if (rootR == r) {
3834                        Binder.restoreCallingIdentity(origId);
3835                        return false;
3836                    }
3837                }
3838                boolean res = false;
3839                if (r != null) {
3840                    res = r.task.stack.finishActivityAffinityLocked(r);
3841                }
3842                return res;
3843            } finally {
3844                Binder.restoreCallingIdentity(origId);
3845            }
3846        }
3847    }
3848
3849    @Override
3850    public boolean willActivityBeVisible(IBinder token) {
3851        synchronized(this) {
3852            ActivityStack stack = ActivityRecord.getStackLocked(token);
3853            if (stack != null) {
3854                return stack.willActivityBeVisibleLocked(token);
3855            }
3856            return false;
3857        }
3858    }
3859
3860    @Override
3861    public void overridePendingTransition(IBinder token, String packageName,
3862            int enterAnim, int exitAnim) {
3863        synchronized(this) {
3864            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3865            if (self == null) {
3866                return;
3867            }
3868
3869            final long origId = Binder.clearCallingIdentity();
3870
3871            if (self.state == ActivityState.RESUMED
3872                    || self.state == ActivityState.PAUSING) {
3873                mWindowManager.overridePendingAppTransition(packageName,
3874                        enterAnim, exitAnim, null);
3875            }
3876
3877            Binder.restoreCallingIdentity(origId);
3878        }
3879    }
3880
3881    /**
3882     * Main function for removing an existing process from the activity manager
3883     * as a result of that process going away.  Clears out all connections
3884     * to the process.
3885     */
3886    private final void handleAppDiedLocked(ProcessRecord app,
3887            boolean restarting, boolean allowRestart) {
3888        int pid = app.pid;
3889        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3890        if (!restarting) {
3891            removeLruProcessLocked(app);
3892            if (pid > 0) {
3893                ProcessList.remove(pid);
3894            }
3895        }
3896
3897        if (mProfileProc == app) {
3898            clearProfilerLocked();
3899        }
3900
3901        // Remove this application's activities from active lists.
3902        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3903
3904        app.activities.clear();
3905
3906        if (app.instrumentationClass != null) {
3907            Slog.w(TAG, "Crash of app " + app.processName
3908                  + " running instrumentation " + app.instrumentationClass);
3909            Bundle info = new Bundle();
3910            info.putString("shortMsg", "Process crashed.");
3911            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3912        }
3913
3914        if (!restarting) {
3915            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3916                // If there was nothing to resume, and we are not already
3917                // restarting this process, but there is a visible activity that
3918                // is hosted by the process...  then make sure all visible
3919                // activities are running, taking care of restarting this
3920                // process.
3921                if (hasVisibleActivities) {
3922                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3923                }
3924            }
3925        }
3926    }
3927
3928    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3929        IBinder threadBinder = thread.asBinder();
3930        // Find the application record.
3931        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3932            ProcessRecord rec = mLruProcesses.get(i);
3933            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3934                return i;
3935            }
3936        }
3937        return -1;
3938    }
3939
3940    final ProcessRecord getRecordForAppLocked(
3941            IApplicationThread thread) {
3942        if (thread == null) {
3943            return null;
3944        }
3945
3946        int appIndex = getLRURecordIndexForAppLocked(thread);
3947        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3948    }
3949
3950    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3951        // If there are no longer any background processes running,
3952        // and the app that died was not running instrumentation,
3953        // then tell everyone we are now low on memory.
3954        boolean haveBg = false;
3955        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3956            ProcessRecord rec = mLruProcesses.get(i);
3957            if (rec.thread != null
3958                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3959                haveBg = true;
3960                break;
3961            }
3962        }
3963
3964        if (!haveBg) {
3965            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3966            if (doReport) {
3967                long now = SystemClock.uptimeMillis();
3968                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3969                    doReport = false;
3970                } else {
3971                    mLastMemUsageReportTime = now;
3972                }
3973            }
3974            final ArrayList<ProcessMemInfo> memInfos
3975                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3976            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3977            long now = SystemClock.uptimeMillis();
3978            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3979                ProcessRecord rec = mLruProcesses.get(i);
3980                if (rec == dyingProc || rec.thread == null) {
3981                    continue;
3982                }
3983                if (doReport) {
3984                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3985                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3986                }
3987                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3988                    // The low memory report is overriding any current
3989                    // state for a GC request.  Make sure to do
3990                    // heavy/important/visible/foreground processes first.
3991                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3992                        rec.lastRequestedGc = 0;
3993                    } else {
3994                        rec.lastRequestedGc = rec.lastLowMemory;
3995                    }
3996                    rec.reportLowMemory = true;
3997                    rec.lastLowMemory = now;
3998                    mProcessesToGc.remove(rec);
3999                    addProcessToGcListLocked(rec);
4000                }
4001            }
4002            if (doReport) {
4003                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4004                mHandler.sendMessage(msg);
4005            }
4006            scheduleAppGcsLocked();
4007        }
4008    }
4009
4010    final void appDiedLocked(ProcessRecord app, int pid,
4011            IApplicationThread thread) {
4012
4013        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4014        synchronized (stats) {
4015            stats.noteProcessDiedLocked(app.info.uid, pid);
4016        }
4017
4018        // Clean up already done if the process has been re-started.
4019        if (app.pid == pid && app.thread != null &&
4020                app.thread.asBinder() == thread.asBinder()) {
4021            boolean doLowMem = app.instrumentationClass == null;
4022            boolean doOomAdj = doLowMem;
4023            if (!app.killedByAm) {
4024                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4025                        + ") has died.");
4026                mAllowLowerMemLevel = true;
4027            } else {
4028                // Note that we always want to do oom adj to update our state with the
4029                // new number of procs.
4030                mAllowLowerMemLevel = false;
4031                doLowMem = false;
4032            }
4033            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4034            if (DEBUG_CLEANUP) Slog.v(
4035                TAG, "Dying app: " + app + ", pid: " + pid
4036                + ", thread: " + thread.asBinder());
4037            handleAppDiedLocked(app, false, true);
4038
4039            if (doOomAdj) {
4040                updateOomAdjLocked();
4041            }
4042            if (doLowMem) {
4043                doLowMemReportIfNeededLocked(app);
4044            }
4045        } else if (app.pid != pid) {
4046            // A new process has already been started.
4047            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4048                    + ") has died and restarted (pid " + app.pid + ").");
4049            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4050        } else if (DEBUG_PROCESSES) {
4051            Slog.d(TAG, "Received spurious death notification for thread "
4052                    + thread.asBinder());
4053        }
4054    }
4055
4056    /**
4057     * If a stack trace dump file is configured, dump process stack traces.
4058     * @param clearTraces causes the dump file to be erased prior to the new
4059     *    traces being written, if true; when false, the new traces will be
4060     *    appended to any existing file content.
4061     * @param firstPids of dalvik VM processes to dump stack traces for first
4062     * @param lastPids of dalvik VM processes to dump stack traces for last
4063     * @param nativeProcs optional list of native process names to dump stack crawls
4064     * @return file containing stack traces, or null if no dump file is configured
4065     */
4066    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4067            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4068        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4069        if (tracesPath == null || tracesPath.length() == 0) {
4070            return null;
4071        }
4072
4073        File tracesFile = new File(tracesPath);
4074        try {
4075            File tracesDir = tracesFile.getParentFile();
4076            if (!tracesDir.exists()) {
4077                tracesFile.mkdirs();
4078                if (!SELinux.restorecon(tracesDir)) {
4079                    return null;
4080                }
4081            }
4082            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4083
4084            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4085            tracesFile.createNewFile();
4086            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4087        } catch (IOException e) {
4088            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4089            return null;
4090        }
4091
4092        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4093        return tracesFile;
4094    }
4095
4096    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4097            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4098        // Use a FileObserver to detect when traces finish writing.
4099        // The order of traces is considered important to maintain for legibility.
4100        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4101            @Override
4102            public synchronized void onEvent(int event, String path) { notify(); }
4103        };
4104
4105        try {
4106            observer.startWatching();
4107
4108            // First collect all of the stacks of the most important pids.
4109            if (firstPids != null) {
4110                try {
4111                    int num = firstPids.size();
4112                    for (int i = 0; i < num; i++) {
4113                        synchronized (observer) {
4114                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4115                            observer.wait(200);  // Wait for write-close, give up after 200msec
4116                        }
4117                    }
4118                } catch (InterruptedException e) {
4119                    Log.wtf(TAG, e);
4120                }
4121            }
4122
4123            // Next collect the stacks of the native pids
4124            if (nativeProcs != null) {
4125                int[] pids = Process.getPidsForCommands(nativeProcs);
4126                if (pids != null) {
4127                    for (int pid : pids) {
4128                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4129                    }
4130                }
4131            }
4132
4133            // Lastly, measure CPU usage.
4134            if (processCpuTracker != null) {
4135                processCpuTracker.init();
4136                System.gc();
4137                processCpuTracker.update();
4138                try {
4139                    synchronized (processCpuTracker) {
4140                        processCpuTracker.wait(500); // measure over 1/2 second.
4141                    }
4142                } catch (InterruptedException e) {
4143                }
4144                processCpuTracker.update();
4145
4146                // We'll take the stack crawls of just the top apps using CPU.
4147                final int N = processCpuTracker.countWorkingStats();
4148                int numProcs = 0;
4149                for (int i=0; i<N && numProcs<5; i++) {
4150                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4151                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4152                        numProcs++;
4153                        try {
4154                            synchronized (observer) {
4155                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4156                                observer.wait(200);  // Wait for write-close, give up after 200msec
4157                            }
4158                        } catch (InterruptedException e) {
4159                            Log.wtf(TAG, e);
4160                        }
4161
4162                    }
4163                }
4164            }
4165        } finally {
4166            observer.stopWatching();
4167        }
4168    }
4169
4170    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4171        if (true || IS_USER_BUILD) {
4172            return;
4173        }
4174        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4175        if (tracesPath == null || tracesPath.length() == 0) {
4176            return;
4177        }
4178
4179        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4180        StrictMode.allowThreadDiskWrites();
4181        try {
4182            final File tracesFile = new File(tracesPath);
4183            final File tracesDir = tracesFile.getParentFile();
4184            final File tracesTmp = new File(tracesDir, "__tmp__");
4185            try {
4186                if (!tracesDir.exists()) {
4187                    tracesFile.mkdirs();
4188                    if (!SELinux.restorecon(tracesDir.getPath())) {
4189                        return;
4190                    }
4191                }
4192                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4193
4194                if (tracesFile.exists()) {
4195                    tracesTmp.delete();
4196                    tracesFile.renameTo(tracesTmp);
4197                }
4198                StringBuilder sb = new StringBuilder();
4199                Time tobj = new Time();
4200                tobj.set(System.currentTimeMillis());
4201                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4202                sb.append(": ");
4203                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4204                sb.append(" since ");
4205                sb.append(msg);
4206                FileOutputStream fos = new FileOutputStream(tracesFile);
4207                fos.write(sb.toString().getBytes());
4208                if (app == null) {
4209                    fos.write("\n*** No application process!".getBytes());
4210                }
4211                fos.close();
4212                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4213            } catch (IOException e) {
4214                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4215                return;
4216            }
4217
4218            if (app != null) {
4219                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4220                firstPids.add(app.pid);
4221                dumpStackTraces(tracesPath, firstPids, null, null, null);
4222            }
4223
4224            File lastTracesFile = null;
4225            File curTracesFile = null;
4226            for (int i=9; i>=0; i--) {
4227                String name = String.format(Locale.US, "slow%02d.txt", i);
4228                curTracesFile = new File(tracesDir, name);
4229                if (curTracesFile.exists()) {
4230                    if (lastTracesFile != null) {
4231                        curTracesFile.renameTo(lastTracesFile);
4232                    } else {
4233                        curTracesFile.delete();
4234                    }
4235                }
4236                lastTracesFile = curTracesFile;
4237            }
4238            tracesFile.renameTo(curTracesFile);
4239            if (tracesTmp.exists()) {
4240                tracesTmp.renameTo(tracesFile);
4241            }
4242        } finally {
4243            StrictMode.setThreadPolicy(oldPolicy);
4244        }
4245    }
4246
4247    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4248            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4249        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4250        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4251
4252        if (mController != null) {
4253            try {
4254                // 0 == continue, -1 = kill process immediately
4255                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4256                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4257            } catch (RemoteException e) {
4258                mController = null;
4259                Watchdog.getInstance().setActivityController(null);
4260            }
4261        }
4262
4263        long anrTime = SystemClock.uptimeMillis();
4264        if (MONITOR_CPU_USAGE) {
4265            updateCpuStatsNow();
4266        }
4267
4268        synchronized (this) {
4269            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4270            if (mShuttingDown) {
4271                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4272                return;
4273            } else if (app.notResponding) {
4274                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4275                return;
4276            } else if (app.crashing) {
4277                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4278                return;
4279            }
4280
4281            // In case we come through here for the same app before completing
4282            // this one, mark as anring now so we will bail out.
4283            app.notResponding = true;
4284
4285            // Log the ANR to the event log.
4286            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4287                    app.processName, app.info.flags, annotation);
4288
4289            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4290            firstPids.add(app.pid);
4291
4292            int parentPid = app.pid;
4293            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4294            if (parentPid != app.pid) firstPids.add(parentPid);
4295
4296            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4297
4298            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4299                ProcessRecord r = mLruProcesses.get(i);
4300                if (r != null && r.thread != null) {
4301                    int pid = r.pid;
4302                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4303                        if (r.persistent) {
4304                            firstPids.add(pid);
4305                        } else {
4306                            lastPids.put(pid, Boolean.TRUE);
4307                        }
4308                    }
4309                }
4310            }
4311        }
4312
4313        // Log the ANR to the main log.
4314        StringBuilder info = new StringBuilder();
4315        info.setLength(0);
4316        info.append("ANR in ").append(app.processName);
4317        if (activity != null && activity.shortComponentName != null) {
4318            info.append(" (").append(activity.shortComponentName).append(")");
4319        }
4320        info.append("\n");
4321        info.append("PID: ").append(app.pid).append("\n");
4322        if (annotation != null) {
4323            info.append("Reason: ").append(annotation).append("\n");
4324        }
4325        if (parent != null && parent != activity) {
4326            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4327        }
4328
4329        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4330
4331        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4332                NATIVE_STACKS_OF_INTEREST);
4333
4334        String cpuInfo = null;
4335        if (MONITOR_CPU_USAGE) {
4336            updateCpuStatsNow();
4337            synchronized (mProcessCpuThread) {
4338                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4339            }
4340            info.append(processCpuTracker.printCurrentLoad());
4341            info.append(cpuInfo);
4342        }
4343
4344        info.append(processCpuTracker.printCurrentState(anrTime));
4345
4346        Slog.e(TAG, info.toString());
4347        if (tracesFile == null) {
4348            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4349            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4350        }
4351
4352        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4353                cpuInfo, tracesFile, null);
4354
4355        if (mController != null) {
4356            try {
4357                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4358                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4359                if (res != 0) {
4360                    if (res < 0 && app.pid != MY_PID) {
4361                        Process.killProcess(app.pid);
4362                    } else {
4363                        synchronized (this) {
4364                            mServices.scheduleServiceTimeoutLocked(app);
4365                        }
4366                    }
4367                    return;
4368                }
4369            } catch (RemoteException e) {
4370                mController = null;
4371                Watchdog.getInstance().setActivityController(null);
4372            }
4373        }
4374
4375        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4376        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4377                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4378
4379        synchronized (this) {
4380            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4381                killUnneededProcessLocked(app, "background ANR");
4382                return;
4383            }
4384
4385            // Set the app's notResponding state, and look up the errorReportReceiver
4386            makeAppNotRespondingLocked(app,
4387                    activity != null ? activity.shortComponentName : null,
4388                    annotation != null ? "ANR " + annotation : "ANR",
4389                    info.toString());
4390
4391            // Bring up the infamous App Not Responding dialog
4392            Message msg = Message.obtain();
4393            HashMap<String, Object> map = new HashMap<String, Object>();
4394            msg.what = SHOW_NOT_RESPONDING_MSG;
4395            msg.obj = map;
4396            msg.arg1 = aboveSystem ? 1 : 0;
4397            map.put("app", app);
4398            if (activity != null) {
4399                map.put("activity", activity);
4400            }
4401
4402            mHandler.sendMessage(msg);
4403        }
4404    }
4405
4406    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4407        if (!mLaunchWarningShown) {
4408            mLaunchWarningShown = true;
4409            mHandler.post(new Runnable() {
4410                @Override
4411                public void run() {
4412                    synchronized (ActivityManagerService.this) {
4413                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4414                        d.show();
4415                        mHandler.postDelayed(new Runnable() {
4416                            @Override
4417                            public void run() {
4418                                synchronized (ActivityManagerService.this) {
4419                                    d.dismiss();
4420                                    mLaunchWarningShown = false;
4421                                }
4422                            }
4423                        }, 4000);
4424                    }
4425                }
4426            });
4427        }
4428    }
4429
4430    @Override
4431    public boolean clearApplicationUserData(final String packageName,
4432            final IPackageDataObserver observer, int userId) {
4433        enforceNotIsolatedCaller("clearApplicationUserData");
4434        int uid = Binder.getCallingUid();
4435        int pid = Binder.getCallingPid();
4436        userId = handleIncomingUser(pid, uid,
4437                userId, false, true, "clearApplicationUserData", null);
4438        long callingId = Binder.clearCallingIdentity();
4439        try {
4440            IPackageManager pm = AppGlobals.getPackageManager();
4441            int pkgUid = -1;
4442            synchronized(this) {
4443                try {
4444                    pkgUid = pm.getPackageUid(packageName, userId);
4445                } catch (RemoteException e) {
4446                }
4447                if (pkgUid == -1) {
4448                    Slog.w(TAG, "Invalid packageName: " + packageName);
4449                    if (observer != null) {
4450                        try {
4451                            observer.onRemoveCompleted(packageName, false);
4452                        } catch (RemoteException e) {
4453                            Slog.i(TAG, "Observer no longer exists.");
4454                        }
4455                    }
4456                    return false;
4457                }
4458                if (uid == pkgUid || checkComponentPermission(
4459                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4460                        pid, uid, -1, true)
4461                        == PackageManager.PERMISSION_GRANTED) {
4462                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4463                } else {
4464                    throw new SecurityException("PID " + pid + " does not have permission "
4465                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4466                                    + " of package " + packageName);
4467                }
4468            }
4469
4470            try {
4471                // Clear application user data
4472                pm.clearApplicationUserData(packageName, observer, userId);
4473
4474                // Remove all permissions granted from/to this package
4475                removeUriPermissionsForPackageLocked(packageName, userId, true);
4476
4477                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4478                        Uri.fromParts("package", packageName, null));
4479                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4480                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4481                        null, null, 0, null, null, null, false, false, userId);
4482            } catch (RemoteException e) {
4483            }
4484        } finally {
4485            Binder.restoreCallingIdentity(callingId);
4486        }
4487        return true;
4488    }
4489
4490    @Override
4491    public void killBackgroundProcesses(final String packageName, int userId) {
4492        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4493                != PackageManager.PERMISSION_GRANTED &&
4494                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4495                        != PackageManager.PERMISSION_GRANTED) {
4496            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4497                    + Binder.getCallingPid()
4498                    + ", uid=" + Binder.getCallingUid()
4499                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4500            Slog.w(TAG, msg);
4501            throw new SecurityException(msg);
4502        }
4503
4504        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4505                userId, true, true, "killBackgroundProcesses", null);
4506        long callingId = Binder.clearCallingIdentity();
4507        try {
4508            IPackageManager pm = AppGlobals.getPackageManager();
4509            synchronized(this) {
4510                int appId = -1;
4511                try {
4512                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4513                } catch (RemoteException e) {
4514                }
4515                if (appId == -1) {
4516                    Slog.w(TAG, "Invalid packageName: " + packageName);
4517                    return;
4518                }
4519                killPackageProcessesLocked(packageName, appId, userId,
4520                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4521            }
4522        } finally {
4523            Binder.restoreCallingIdentity(callingId);
4524        }
4525    }
4526
4527    @Override
4528    public void killAllBackgroundProcesses() {
4529        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4530                != PackageManager.PERMISSION_GRANTED) {
4531            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4532                    + Binder.getCallingPid()
4533                    + ", uid=" + Binder.getCallingUid()
4534                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4535            Slog.w(TAG, msg);
4536            throw new SecurityException(msg);
4537        }
4538
4539        long callingId = Binder.clearCallingIdentity();
4540        try {
4541            synchronized(this) {
4542                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4543                final int NP = mProcessNames.getMap().size();
4544                for (int ip=0; ip<NP; ip++) {
4545                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4546                    final int NA = apps.size();
4547                    for (int ia=0; ia<NA; ia++) {
4548                        ProcessRecord app = apps.valueAt(ia);
4549                        if (app.persistent) {
4550                            // we don't kill persistent processes
4551                            continue;
4552                        }
4553                        if (app.removed) {
4554                            procs.add(app);
4555                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4556                            app.removed = true;
4557                            procs.add(app);
4558                        }
4559                    }
4560                }
4561
4562                int N = procs.size();
4563                for (int i=0; i<N; i++) {
4564                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4565                }
4566                mAllowLowerMemLevel = true;
4567                updateOomAdjLocked();
4568                doLowMemReportIfNeededLocked(null);
4569            }
4570        } finally {
4571            Binder.restoreCallingIdentity(callingId);
4572        }
4573    }
4574
4575    @Override
4576    public void forceStopPackage(final String packageName, int userId) {
4577        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4578                != PackageManager.PERMISSION_GRANTED) {
4579            String msg = "Permission Denial: forceStopPackage() from pid="
4580                    + Binder.getCallingPid()
4581                    + ", uid=" + Binder.getCallingUid()
4582                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4583            Slog.w(TAG, msg);
4584            throw new SecurityException(msg);
4585        }
4586        final int callingPid = Binder.getCallingPid();
4587        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4588                userId, true, true, "forceStopPackage", null);
4589        long callingId = Binder.clearCallingIdentity();
4590        try {
4591            IPackageManager pm = AppGlobals.getPackageManager();
4592            synchronized(this) {
4593                int[] users = userId == UserHandle.USER_ALL
4594                        ? getUsersLocked() : new int[] { userId };
4595                for (int user : users) {
4596                    int pkgUid = -1;
4597                    try {
4598                        pkgUid = pm.getPackageUid(packageName, user);
4599                    } catch (RemoteException e) {
4600                    }
4601                    if (pkgUid == -1) {
4602                        Slog.w(TAG, "Invalid packageName: " + packageName);
4603                        continue;
4604                    }
4605                    try {
4606                        pm.setPackageStoppedState(packageName, true, user);
4607                    } catch (RemoteException e) {
4608                    } catch (IllegalArgumentException e) {
4609                        Slog.w(TAG, "Failed trying to unstop package "
4610                                + packageName + ": " + e);
4611                    }
4612                    if (isUserRunningLocked(user, false)) {
4613                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4614                    }
4615                }
4616            }
4617        } finally {
4618            Binder.restoreCallingIdentity(callingId);
4619        }
4620    }
4621
4622    /*
4623     * The pkg name and app id have to be specified.
4624     */
4625    @Override
4626    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4627        if (pkg == null) {
4628            return;
4629        }
4630        // Make sure the uid is valid.
4631        if (appid < 0) {
4632            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4633            return;
4634        }
4635        int callerUid = Binder.getCallingUid();
4636        // Only the system server can kill an application
4637        if (callerUid == Process.SYSTEM_UID) {
4638            // Post an aysnc message to kill the application
4639            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4640            msg.arg1 = appid;
4641            msg.arg2 = 0;
4642            Bundle bundle = new Bundle();
4643            bundle.putString("pkg", pkg);
4644            bundle.putString("reason", reason);
4645            msg.obj = bundle;
4646            mHandler.sendMessage(msg);
4647        } else {
4648            throw new SecurityException(callerUid + " cannot kill pkg: " +
4649                    pkg);
4650        }
4651    }
4652
4653    @Override
4654    public void closeSystemDialogs(String reason) {
4655        enforceNotIsolatedCaller("closeSystemDialogs");
4656
4657        final int pid = Binder.getCallingPid();
4658        final int uid = Binder.getCallingUid();
4659        final long origId = Binder.clearCallingIdentity();
4660        try {
4661            synchronized (this) {
4662                // Only allow this from foreground processes, so that background
4663                // applications can't abuse it to prevent system UI from being shown.
4664                if (uid >= Process.FIRST_APPLICATION_UID) {
4665                    ProcessRecord proc;
4666                    synchronized (mPidsSelfLocked) {
4667                        proc = mPidsSelfLocked.get(pid);
4668                    }
4669                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4670                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4671                                + " from background process " + proc);
4672                        return;
4673                    }
4674                }
4675                closeSystemDialogsLocked(reason);
4676            }
4677        } finally {
4678            Binder.restoreCallingIdentity(origId);
4679        }
4680    }
4681
4682    void closeSystemDialogsLocked(String reason) {
4683        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4684        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4685                | Intent.FLAG_RECEIVER_FOREGROUND);
4686        if (reason != null) {
4687            intent.putExtra("reason", reason);
4688        }
4689        mWindowManager.closeSystemDialogs(reason);
4690
4691        mStackSupervisor.closeSystemDialogsLocked();
4692
4693        broadcastIntentLocked(null, null, intent, null,
4694                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4695                Process.SYSTEM_UID, UserHandle.USER_ALL);
4696    }
4697
4698    @Override
4699    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4700        enforceNotIsolatedCaller("getProcessMemoryInfo");
4701        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4702        for (int i=pids.length-1; i>=0; i--) {
4703            ProcessRecord proc;
4704            int oomAdj;
4705            synchronized (this) {
4706                synchronized (mPidsSelfLocked) {
4707                    proc = mPidsSelfLocked.get(pids[i]);
4708                    oomAdj = proc != null ? proc.setAdj : 0;
4709                }
4710            }
4711            infos[i] = new Debug.MemoryInfo();
4712            Debug.getMemoryInfo(pids[i], infos[i]);
4713            if (proc != null) {
4714                synchronized (this) {
4715                    if (proc.thread != null && proc.setAdj == oomAdj) {
4716                        // Record this for posterity if the process has been stable.
4717                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4718                                infos[i].getTotalUss(), false, proc.pkgList);
4719                    }
4720                }
4721            }
4722        }
4723        return infos;
4724    }
4725
4726    @Override
4727    public long[] getProcessPss(int[] pids) {
4728        enforceNotIsolatedCaller("getProcessPss");
4729        long[] pss = new long[pids.length];
4730        for (int i=pids.length-1; i>=0; i--) {
4731            ProcessRecord proc;
4732            int oomAdj;
4733            synchronized (this) {
4734                synchronized (mPidsSelfLocked) {
4735                    proc = mPidsSelfLocked.get(pids[i]);
4736                    oomAdj = proc != null ? proc.setAdj : 0;
4737                }
4738            }
4739            long[] tmpUss = new long[1];
4740            pss[i] = Debug.getPss(pids[i], tmpUss);
4741            if (proc != null) {
4742                synchronized (this) {
4743                    if (proc.thread != null && proc.setAdj == oomAdj) {
4744                        // Record this for posterity if the process has been stable.
4745                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4746                    }
4747                }
4748            }
4749        }
4750        return pss;
4751    }
4752
4753    @Override
4754    public void killApplicationProcess(String processName, int uid) {
4755        if (processName == null) {
4756            return;
4757        }
4758
4759        int callerUid = Binder.getCallingUid();
4760        // Only the system server can kill an application
4761        if (callerUid == Process.SYSTEM_UID) {
4762            synchronized (this) {
4763                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4764                if (app != null && app.thread != null) {
4765                    try {
4766                        app.thread.scheduleSuicide();
4767                    } catch (RemoteException e) {
4768                        // If the other end already died, then our work here is done.
4769                    }
4770                } else {
4771                    Slog.w(TAG, "Process/uid not found attempting kill of "
4772                            + processName + " / " + uid);
4773                }
4774            }
4775        } else {
4776            throw new SecurityException(callerUid + " cannot kill app process: " +
4777                    processName);
4778        }
4779    }
4780
4781    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4782        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4783                false, true, false, false, UserHandle.getUserId(uid), reason);
4784        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4785                Uri.fromParts("package", packageName, null));
4786        if (!mProcessesReady) {
4787            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4788                    | Intent.FLAG_RECEIVER_FOREGROUND);
4789        }
4790        intent.putExtra(Intent.EXTRA_UID, uid);
4791        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4792        broadcastIntentLocked(null, null, intent,
4793                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4794                false, false,
4795                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4796    }
4797
4798    private void forceStopUserLocked(int userId, String reason) {
4799        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4800        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4801        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4802                | Intent.FLAG_RECEIVER_FOREGROUND);
4803        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4804        broadcastIntentLocked(null, null, intent,
4805                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4806                false, false,
4807                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4808    }
4809
4810    private final boolean killPackageProcessesLocked(String packageName, int appId,
4811            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4812            boolean doit, boolean evenPersistent, String reason) {
4813        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4814
4815        // Remove all processes this package may have touched: all with the
4816        // same UID (except for the system or root user), and all whose name
4817        // matches the package name.
4818        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4819        final int NP = mProcessNames.getMap().size();
4820        for (int ip=0; ip<NP; ip++) {
4821            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4822            final int NA = apps.size();
4823            for (int ia=0; ia<NA; ia++) {
4824                ProcessRecord app = apps.valueAt(ia);
4825                if (app.persistent && !evenPersistent) {
4826                    // we don't kill persistent processes
4827                    continue;
4828                }
4829                if (app.removed) {
4830                    if (doit) {
4831                        procs.add(app);
4832                    }
4833                    continue;
4834                }
4835
4836                // Skip process if it doesn't meet our oom adj requirement.
4837                if (app.setAdj < minOomAdj) {
4838                    continue;
4839                }
4840
4841                // If no package is specified, we call all processes under the
4842                // give user id.
4843                if (packageName == null) {
4844                    if (app.userId != userId) {
4845                        continue;
4846                    }
4847                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4848                        continue;
4849                    }
4850                // Package has been specified, we want to hit all processes
4851                // that match it.  We need to qualify this by the processes
4852                // that are running under the specified app and user ID.
4853                } else {
4854                    if (UserHandle.getAppId(app.uid) != appId) {
4855                        continue;
4856                    }
4857                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4858                        continue;
4859                    }
4860                    if (!app.pkgList.containsKey(packageName)) {
4861                        continue;
4862                    }
4863                }
4864
4865                // Process has passed all conditions, kill it!
4866                if (!doit) {
4867                    return true;
4868                }
4869                app.removed = true;
4870                procs.add(app);
4871            }
4872        }
4873
4874        int N = procs.size();
4875        for (int i=0; i<N; i++) {
4876            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4877        }
4878        updateOomAdjLocked();
4879        return N > 0;
4880    }
4881
4882    private final boolean forceStopPackageLocked(String name, int appId,
4883            boolean callerWillRestart, boolean purgeCache, boolean doit,
4884            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4885        int i;
4886        int N;
4887
4888        if (userId == UserHandle.USER_ALL && name == null) {
4889            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4890        }
4891
4892        if (appId < 0 && name != null) {
4893            try {
4894                appId = UserHandle.getAppId(
4895                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4896            } catch (RemoteException e) {
4897            }
4898        }
4899
4900        if (doit) {
4901            if (name != null) {
4902                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4903                        + " user=" + userId + ": " + reason);
4904            } else {
4905                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4906            }
4907
4908            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4909            for (int ip=pmap.size()-1; ip>=0; ip--) {
4910                SparseArray<Long> ba = pmap.valueAt(ip);
4911                for (i=ba.size()-1; i>=0; i--) {
4912                    boolean remove = false;
4913                    final int entUid = ba.keyAt(i);
4914                    if (name != null) {
4915                        if (userId == UserHandle.USER_ALL) {
4916                            if (UserHandle.getAppId(entUid) == appId) {
4917                                remove = true;
4918                            }
4919                        } else {
4920                            if (entUid == UserHandle.getUid(userId, appId)) {
4921                                remove = true;
4922                            }
4923                        }
4924                    } else if (UserHandle.getUserId(entUid) == userId) {
4925                        remove = true;
4926                    }
4927                    if (remove) {
4928                        ba.removeAt(i);
4929                    }
4930                }
4931                if (ba.size() == 0) {
4932                    pmap.removeAt(ip);
4933                }
4934            }
4935        }
4936
4937        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4938                -100, callerWillRestart, true, doit, evenPersistent,
4939                name == null ? ("stop user " + userId) : ("stop " + name));
4940
4941        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4942            if (!doit) {
4943                return true;
4944            }
4945            didSomething = true;
4946        }
4947
4948        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4949            if (!doit) {
4950                return true;
4951            }
4952            didSomething = true;
4953        }
4954
4955        if (name == null) {
4956            // Remove all sticky broadcasts from this user.
4957            mStickyBroadcasts.remove(userId);
4958        }
4959
4960        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4961        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4962                userId, providers)) {
4963            if (!doit) {
4964                return true;
4965            }
4966            didSomething = true;
4967        }
4968        N = providers.size();
4969        for (i=0; i<N; i++) {
4970            removeDyingProviderLocked(null, providers.get(i), true);
4971        }
4972
4973        // Remove transient permissions granted from/to this package/user
4974        removeUriPermissionsForPackageLocked(name, userId, false);
4975
4976        if (name == null || uninstalling) {
4977            // Remove pending intents.  For now we only do this when force
4978            // stopping users, because we have some problems when doing this
4979            // for packages -- app widgets are not currently cleaned up for
4980            // such packages, so they can be left with bad pending intents.
4981            if (mIntentSenderRecords.size() > 0) {
4982                Iterator<WeakReference<PendingIntentRecord>> it
4983                        = mIntentSenderRecords.values().iterator();
4984                while (it.hasNext()) {
4985                    WeakReference<PendingIntentRecord> wpir = it.next();
4986                    if (wpir == null) {
4987                        it.remove();
4988                        continue;
4989                    }
4990                    PendingIntentRecord pir = wpir.get();
4991                    if (pir == null) {
4992                        it.remove();
4993                        continue;
4994                    }
4995                    if (name == null) {
4996                        // Stopping user, remove all objects for the user.
4997                        if (pir.key.userId != userId) {
4998                            // Not the same user, skip it.
4999                            continue;
5000                        }
5001                    } else {
5002                        if (UserHandle.getAppId(pir.uid) != appId) {
5003                            // Different app id, skip it.
5004                            continue;
5005                        }
5006                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5007                            // Different user, skip it.
5008                            continue;
5009                        }
5010                        if (!pir.key.packageName.equals(name)) {
5011                            // Different package, skip it.
5012                            continue;
5013                        }
5014                    }
5015                    if (!doit) {
5016                        return true;
5017                    }
5018                    didSomething = true;
5019                    it.remove();
5020                    pir.canceled = true;
5021                    if (pir.key.activity != null) {
5022                        pir.key.activity.pendingResults.remove(pir.ref);
5023                    }
5024                }
5025            }
5026        }
5027
5028        if (doit) {
5029            if (purgeCache && name != null) {
5030                AttributeCache ac = AttributeCache.instance();
5031                if (ac != null) {
5032                    ac.removePackage(name);
5033                }
5034            }
5035            if (mBooted) {
5036                mStackSupervisor.resumeTopActivitiesLocked();
5037                mStackSupervisor.scheduleIdleLocked();
5038            }
5039        }
5040
5041        return didSomething;
5042    }
5043
5044    private final boolean removeProcessLocked(ProcessRecord app,
5045            boolean callerWillRestart, boolean allowRestart, String reason) {
5046        final String name = app.processName;
5047        final int uid = app.uid;
5048        if (DEBUG_PROCESSES) Slog.d(
5049            TAG, "Force removing proc " + app.toShortString() + " (" + name
5050            + "/" + uid + ")");
5051
5052        mProcessNames.remove(name, uid);
5053        mIsolatedProcesses.remove(app.uid);
5054        if (mHeavyWeightProcess == app) {
5055            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5056                    mHeavyWeightProcess.userId, 0));
5057            mHeavyWeightProcess = null;
5058        }
5059        boolean needRestart = false;
5060        if (app.pid > 0 && app.pid != MY_PID) {
5061            int pid = app.pid;
5062            synchronized (mPidsSelfLocked) {
5063                mPidsSelfLocked.remove(pid);
5064                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5065            }
5066            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5067                    app.processName, app.info.uid);
5068            if (app.isolated) {
5069                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5070            }
5071            killUnneededProcessLocked(app, reason);
5072            handleAppDiedLocked(app, true, allowRestart);
5073            removeLruProcessLocked(app);
5074
5075            if (app.persistent && !app.isolated) {
5076                if (!callerWillRestart) {
5077                    addAppLocked(app.info, false, null /* ABI override */);
5078                } else {
5079                    needRestart = true;
5080                }
5081            }
5082        } else {
5083            mRemovedProcesses.add(app);
5084        }
5085
5086        return needRestart;
5087    }
5088
5089    private final void processStartTimedOutLocked(ProcessRecord app) {
5090        final int pid = app.pid;
5091        boolean gone = false;
5092        synchronized (mPidsSelfLocked) {
5093            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5094            if (knownApp != null && knownApp.thread == null) {
5095                mPidsSelfLocked.remove(pid);
5096                gone = true;
5097            }
5098        }
5099
5100        if (gone) {
5101            Slog.w(TAG, "Process " + app + " failed to attach");
5102            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5103                    pid, app.uid, app.processName);
5104            mProcessNames.remove(app.processName, app.uid);
5105            mIsolatedProcesses.remove(app.uid);
5106            if (mHeavyWeightProcess == app) {
5107                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5108                        mHeavyWeightProcess.userId, 0));
5109                mHeavyWeightProcess = null;
5110            }
5111            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5112                    app.processName, app.info.uid);
5113            if (app.isolated) {
5114                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5115            }
5116            // Take care of any launching providers waiting for this process.
5117            checkAppInLaunchingProvidersLocked(app, true);
5118            // Take care of any services that are waiting for the process.
5119            mServices.processStartTimedOutLocked(app);
5120            killUnneededProcessLocked(app, "start timeout");
5121            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5122                Slog.w(TAG, "Unattached app died before backup, skipping");
5123                try {
5124                    IBackupManager bm = IBackupManager.Stub.asInterface(
5125                            ServiceManager.getService(Context.BACKUP_SERVICE));
5126                    bm.agentDisconnected(app.info.packageName);
5127                } catch (RemoteException e) {
5128                    // Can't happen; the backup manager is local
5129                }
5130            }
5131            if (isPendingBroadcastProcessLocked(pid)) {
5132                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5133                skipPendingBroadcastLocked(pid);
5134            }
5135        } else {
5136            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5137        }
5138    }
5139
5140    private final boolean attachApplicationLocked(IApplicationThread thread,
5141            int pid) {
5142
5143        // Find the application record that is being attached...  either via
5144        // the pid if we are running in multiple processes, or just pull the
5145        // next app record if we are emulating process with anonymous threads.
5146        ProcessRecord app;
5147        if (pid != MY_PID && pid >= 0) {
5148            synchronized (mPidsSelfLocked) {
5149                app = mPidsSelfLocked.get(pid);
5150            }
5151        } else {
5152            app = null;
5153        }
5154
5155        if (app == null) {
5156            Slog.w(TAG, "No pending application record for pid " + pid
5157                    + " (IApplicationThread " + thread + "); dropping process");
5158            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5159            if (pid > 0 && pid != MY_PID) {
5160                Process.killProcessQuiet(pid);
5161            } else {
5162                try {
5163                    thread.scheduleExit();
5164                } catch (Exception e) {
5165                    // Ignore exceptions.
5166                }
5167            }
5168            return false;
5169        }
5170
5171        // If this application record is still attached to a previous
5172        // process, clean it up now.
5173        if (app.thread != null) {
5174            handleAppDiedLocked(app, true, true);
5175        }
5176
5177        // Tell the process all about itself.
5178
5179        if (localLOGV) Slog.v(
5180                TAG, "Binding process pid " + pid + " to record " + app);
5181
5182        final String processName = app.processName;
5183        try {
5184            AppDeathRecipient adr = new AppDeathRecipient(
5185                    app, pid, thread);
5186            thread.asBinder().linkToDeath(adr, 0);
5187            app.deathRecipient = adr;
5188        } catch (RemoteException e) {
5189            app.resetPackageList(mProcessStats);
5190            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5191            return false;
5192        }
5193
5194        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5195
5196        app.makeActive(thread, mProcessStats);
5197        app.curAdj = app.setAdj = -100;
5198        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5199        app.forcingToForeground = null;
5200        updateProcessForegroundLocked(app, false, false);
5201        app.hasShownUi = false;
5202        app.debugging = false;
5203        app.cached = false;
5204
5205        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5206
5207        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5208        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5209
5210        if (!normalMode) {
5211            Slog.i(TAG, "Launching preboot mode app: " + app);
5212        }
5213
5214        if (localLOGV) Slog.v(
5215            TAG, "New app record " + app
5216            + " thread=" + thread.asBinder() + " pid=" + pid);
5217        try {
5218            int testMode = IApplicationThread.DEBUG_OFF;
5219            if (mDebugApp != null && mDebugApp.equals(processName)) {
5220                testMode = mWaitForDebugger
5221                    ? IApplicationThread.DEBUG_WAIT
5222                    : IApplicationThread.DEBUG_ON;
5223                app.debugging = true;
5224                if (mDebugTransient) {
5225                    mDebugApp = mOrigDebugApp;
5226                    mWaitForDebugger = mOrigWaitForDebugger;
5227                }
5228            }
5229            String profileFile = app.instrumentationProfileFile;
5230            ParcelFileDescriptor profileFd = null;
5231            boolean profileAutoStop = false;
5232            if (mProfileApp != null && mProfileApp.equals(processName)) {
5233                mProfileProc = app;
5234                profileFile = mProfileFile;
5235                profileFd = mProfileFd;
5236                profileAutoStop = mAutoStopProfiler;
5237            }
5238            boolean enableOpenGlTrace = false;
5239            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5240                enableOpenGlTrace = true;
5241                mOpenGlTraceApp = null;
5242            }
5243
5244            // If the app is being launched for restore or full backup, set it up specially
5245            boolean isRestrictedBackupMode = false;
5246            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5247                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5248                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5249                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5250            }
5251
5252            ensurePackageDexOpt(app.instrumentationInfo != null
5253                    ? app.instrumentationInfo.packageName
5254                    : app.info.packageName);
5255            if (app.instrumentationClass != null) {
5256                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5257            }
5258            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5259                    + processName + " with config " + mConfiguration);
5260            ApplicationInfo appInfo = app.instrumentationInfo != null
5261                    ? app.instrumentationInfo : app.info;
5262            app.compat = compatibilityInfoForPackageLocked(appInfo);
5263            if (profileFd != null) {
5264                profileFd = profileFd.dup();
5265            }
5266            thread.bindApplication(processName, appInfo, providers,
5267                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5268                    app.instrumentationArguments, app.instrumentationWatcher,
5269                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5270                    isRestrictedBackupMode || !normalMode, app.persistent,
5271                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5272                    mCoreSettingsObserver.getCoreSettingsLocked());
5273            updateLruProcessLocked(app, false, null);
5274            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5275        } catch (Exception e) {
5276            // todo: Yikes!  What should we do?  For now we will try to
5277            // start another process, but that could easily get us in
5278            // an infinite loop of restarting processes...
5279            Slog.w(TAG, "Exception thrown during bind!", e);
5280
5281            app.resetPackageList(mProcessStats);
5282            app.unlinkDeathRecipient();
5283            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5284            return false;
5285        }
5286
5287        // Remove this record from the list of starting applications.
5288        mPersistentStartingProcesses.remove(app);
5289        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5290                "Attach application locked removing on hold: " + app);
5291        mProcessesOnHold.remove(app);
5292
5293        boolean badApp = false;
5294        boolean didSomething = false;
5295
5296        // See if the top visible activity is waiting to run in this process...
5297        if (normalMode) {
5298            try {
5299                if (mStackSupervisor.attachApplicationLocked(app)) {
5300                    didSomething = true;
5301                }
5302            } catch (Exception e) {
5303                badApp = true;
5304            }
5305        }
5306
5307        // Find any services that should be running in this process...
5308        if (!badApp) {
5309            try {
5310                didSomething |= mServices.attachApplicationLocked(app, processName);
5311            } catch (Exception e) {
5312                badApp = true;
5313            }
5314        }
5315
5316        // Check if a next-broadcast receiver is in this process...
5317        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5318            try {
5319                didSomething |= sendPendingBroadcastsLocked(app);
5320            } catch (Exception e) {
5321                // If the app died trying to launch the receiver we declare it 'bad'
5322                badApp = true;
5323            }
5324        }
5325
5326        // Check whether the next backup agent is in this process...
5327        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5328            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5329            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5330            try {
5331                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5332                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5333                        mBackupTarget.backupMode);
5334            } catch (Exception e) {
5335                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5336                e.printStackTrace();
5337            }
5338        }
5339
5340        if (badApp) {
5341            // todo: Also need to kill application to deal with all
5342            // kinds of exceptions.
5343            handleAppDiedLocked(app, false, true);
5344            return false;
5345        }
5346
5347        if (!didSomething) {
5348            updateOomAdjLocked();
5349        }
5350
5351        return true;
5352    }
5353
5354    @Override
5355    public final void attachApplication(IApplicationThread thread) {
5356        synchronized (this) {
5357            int callingPid = Binder.getCallingPid();
5358            final long origId = Binder.clearCallingIdentity();
5359            attachApplicationLocked(thread, callingPid);
5360            Binder.restoreCallingIdentity(origId);
5361        }
5362    }
5363
5364    @Override
5365    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5366        final long origId = Binder.clearCallingIdentity();
5367        synchronized (this) {
5368            ActivityStack stack = ActivityRecord.getStackLocked(token);
5369            if (stack != null) {
5370                ActivityRecord r =
5371                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5372                if (stopProfiling) {
5373                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5374                        try {
5375                            mProfileFd.close();
5376                        } catch (IOException e) {
5377                        }
5378                        clearProfilerLocked();
5379                    }
5380                }
5381            }
5382        }
5383        Binder.restoreCallingIdentity(origId);
5384    }
5385
5386    void enableScreenAfterBoot() {
5387        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5388                SystemClock.uptimeMillis());
5389        mWindowManager.enableScreenAfterBoot();
5390
5391        synchronized (this) {
5392            updateEventDispatchingLocked();
5393        }
5394    }
5395
5396    @Override
5397    public void showBootMessage(final CharSequence msg, final boolean always) {
5398        enforceNotIsolatedCaller("showBootMessage");
5399        mWindowManager.showBootMessage(msg, always);
5400    }
5401
5402    @Override
5403    public void dismissKeyguardOnNextActivity() {
5404        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5405        final long token = Binder.clearCallingIdentity();
5406        try {
5407            synchronized (this) {
5408                if (DEBUG_LOCKSCREEN) logLockScreen("");
5409                if (mLockScreenShown) {
5410                    mLockScreenShown = false;
5411                    comeOutOfSleepIfNeededLocked();
5412                }
5413                mStackSupervisor.setDismissKeyguard(true);
5414            }
5415        } finally {
5416            Binder.restoreCallingIdentity(token);
5417        }
5418    }
5419
5420    final void finishBooting() {
5421        // Register receivers to handle package update events
5422        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5423
5424        synchronized (this) {
5425            // Ensure that any processes we had put on hold are now started
5426            // up.
5427            final int NP = mProcessesOnHold.size();
5428            if (NP > 0) {
5429                ArrayList<ProcessRecord> procs =
5430                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5431                for (int ip=0; ip<NP; ip++) {
5432                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5433                            + procs.get(ip));
5434                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5435                }
5436            }
5437
5438            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5439                // Start looking for apps that are abusing wake locks.
5440                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5441                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5442                // Tell anyone interested that we are done booting!
5443                SystemProperties.set("sys.boot_completed", "1");
5444                SystemProperties.set("dev.bootcomplete", "1");
5445                for (int i=0; i<mStartedUsers.size(); i++) {
5446                    UserStartedState uss = mStartedUsers.valueAt(i);
5447                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5448                        uss.mState = UserStartedState.STATE_RUNNING;
5449                        final int userId = mStartedUsers.keyAt(i);
5450                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5451                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5452                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5453                        broadcastIntentLocked(null, null, intent, null,
5454                                new IIntentReceiver.Stub() {
5455                                    @Override
5456                                    public void performReceive(Intent intent, int resultCode,
5457                                            String data, Bundle extras, boolean ordered,
5458                                            boolean sticky, int sendingUser) {
5459                                        synchronized (ActivityManagerService.this) {
5460                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5461                                                    true, false);
5462                                        }
5463                                    }
5464                                },
5465                                0, null, null,
5466                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5467                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5468                                userId);
5469                    }
5470                }
5471                scheduleStartProfilesLocked();
5472            }
5473        }
5474    }
5475
5476    final void ensureBootCompleted() {
5477        boolean booting;
5478        boolean enableScreen;
5479        synchronized (this) {
5480            booting = mBooting;
5481            mBooting = false;
5482            enableScreen = !mBooted;
5483            mBooted = true;
5484        }
5485
5486        if (booting) {
5487            finishBooting();
5488        }
5489
5490        if (enableScreen) {
5491            enableScreenAfterBoot();
5492        }
5493    }
5494
5495    @Override
5496    public final void activityResumed(IBinder token) {
5497        final long origId = Binder.clearCallingIdentity();
5498        synchronized(this) {
5499            ActivityStack stack = ActivityRecord.getStackLocked(token);
5500            if (stack != null) {
5501                ActivityRecord.activityResumedLocked(token);
5502            }
5503        }
5504        Binder.restoreCallingIdentity(origId);
5505    }
5506
5507    @Override
5508    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5509        final long origId = Binder.clearCallingIdentity();
5510        synchronized(this) {
5511            ActivityStack stack = ActivityRecord.getStackLocked(token);
5512            if (stack != null) {
5513                stack.activityPausedLocked(token, false, persistentState);
5514            }
5515        }
5516        Binder.restoreCallingIdentity(origId);
5517    }
5518
5519    @Override
5520    public final void activityStopped(IBinder token, Bundle icicle,
5521            PersistableBundle persistentState, CharSequence description) {
5522        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5523
5524        // Refuse possible leaked file descriptors
5525        if (icicle != null && icicle.hasFileDescriptors()) {
5526            throw new IllegalArgumentException("File descriptors passed in Bundle");
5527        }
5528
5529        final long origId = Binder.clearCallingIdentity();
5530
5531        synchronized (this) {
5532            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5533            if (r != null) {
5534                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5535            }
5536        }
5537
5538        trimApplications();
5539
5540        Binder.restoreCallingIdentity(origId);
5541    }
5542
5543    @Override
5544    public final void activityDestroyed(IBinder token) {
5545        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5546        synchronized (this) {
5547            ActivityStack stack = ActivityRecord.getStackLocked(token);
5548            if (stack != null) {
5549                stack.activityDestroyedLocked(token);
5550            }
5551        }
5552    }
5553
5554    @Override
5555    public String getCallingPackage(IBinder token) {
5556        synchronized (this) {
5557            ActivityRecord r = getCallingRecordLocked(token);
5558            return r != null ? r.info.packageName : null;
5559        }
5560    }
5561
5562    @Override
5563    public ComponentName getCallingActivity(IBinder token) {
5564        synchronized (this) {
5565            ActivityRecord r = getCallingRecordLocked(token);
5566            return r != null ? r.intent.getComponent() : null;
5567        }
5568    }
5569
5570    private ActivityRecord getCallingRecordLocked(IBinder token) {
5571        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5572        if (r == null) {
5573            return null;
5574        }
5575        return r.resultTo;
5576    }
5577
5578    @Override
5579    public ComponentName getActivityClassForToken(IBinder token) {
5580        synchronized(this) {
5581            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5582            if (r == null) {
5583                return null;
5584            }
5585            return r.intent.getComponent();
5586        }
5587    }
5588
5589    @Override
5590    public String getPackageForToken(IBinder token) {
5591        synchronized(this) {
5592            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5593            if (r == null) {
5594                return null;
5595            }
5596            return r.packageName;
5597        }
5598    }
5599
5600    @Override
5601    public IIntentSender getIntentSender(int type,
5602            String packageName, IBinder token, String resultWho,
5603            int requestCode, Intent[] intents, String[] resolvedTypes,
5604            int flags, Bundle options, int userId) {
5605        enforceNotIsolatedCaller("getIntentSender");
5606        // Refuse possible leaked file descriptors
5607        if (intents != null) {
5608            if (intents.length < 1) {
5609                throw new IllegalArgumentException("Intents array length must be >= 1");
5610            }
5611            for (int i=0; i<intents.length; i++) {
5612                Intent intent = intents[i];
5613                if (intent != null) {
5614                    if (intent.hasFileDescriptors()) {
5615                        throw new IllegalArgumentException("File descriptors passed in Intent");
5616                    }
5617                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5618                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5619                        throw new IllegalArgumentException(
5620                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5621                    }
5622                    intents[i] = new Intent(intent);
5623                }
5624            }
5625            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5626                throw new IllegalArgumentException(
5627                        "Intent array length does not match resolvedTypes length");
5628            }
5629        }
5630        if (options != null) {
5631            if (options.hasFileDescriptors()) {
5632                throw new IllegalArgumentException("File descriptors passed in options");
5633            }
5634        }
5635
5636        synchronized(this) {
5637            int callingUid = Binder.getCallingUid();
5638            int origUserId = userId;
5639            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5640                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5641                    "getIntentSender", null);
5642            if (origUserId == UserHandle.USER_CURRENT) {
5643                // We don't want to evaluate this until the pending intent is
5644                // actually executed.  However, we do want to always do the
5645                // security checking for it above.
5646                userId = UserHandle.USER_CURRENT;
5647            }
5648            try {
5649                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5650                    int uid = AppGlobals.getPackageManager()
5651                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5652                    if (!UserHandle.isSameApp(callingUid, uid)) {
5653                        String msg = "Permission Denial: getIntentSender() from pid="
5654                            + Binder.getCallingPid()
5655                            + ", uid=" + Binder.getCallingUid()
5656                            + ", (need uid=" + uid + ")"
5657                            + " is not allowed to send as package " + packageName;
5658                        Slog.w(TAG, msg);
5659                        throw new SecurityException(msg);
5660                    }
5661                }
5662
5663                return getIntentSenderLocked(type, packageName, callingUid, userId,
5664                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5665
5666            } catch (RemoteException e) {
5667                throw new SecurityException(e);
5668            }
5669        }
5670    }
5671
5672    IIntentSender getIntentSenderLocked(int type, String packageName,
5673            int callingUid, int userId, IBinder token, String resultWho,
5674            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5675            Bundle options) {
5676        if (DEBUG_MU)
5677            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5678        ActivityRecord activity = null;
5679        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5680            activity = ActivityRecord.isInStackLocked(token);
5681            if (activity == null) {
5682                return null;
5683            }
5684            if (activity.finishing) {
5685                return null;
5686            }
5687        }
5688
5689        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5690        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5691        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5692        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5693                |PendingIntent.FLAG_UPDATE_CURRENT);
5694
5695        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5696                type, packageName, activity, resultWho,
5697                requestCode, intents, resolvedTypes, flags, options, userId);
5698        WeakReference<PendingIntentRecord> ref;
5699        ref = mIntentSenderRecords.get(key);
5700        PendingIntentRecord rec = ref != null ? ref.get() : null;
5701        if (rec != null) {
5702            if (!cancelCurrent) {
5703                if (updateCurrent) {
5704                    if (rec.key.requestIntent != null) {
5705                        rec.key.requestIntent.replaceExtras(intents != null ?
5706                                intents[intents.length - 1] : null);
5707                    }
5708                    if (intents != null) {
5709                        intents[intents.length-1] = rec.key.requestIntent;
5710                        rec.key.allIntents = intents;
5711                        rec.key.allResolvedTypes = resolvedTypes;
5712                    } else {
5713                        rec.key.allIntents = null;
5714                        rec.key.allResolvedTypes = null;
5715                    }
5716                }
5717                return rec;
5718            }
5719            rec.canceled = true;
5720            mIntentSenderRecords.remove(key);
5721        }
5722        if (noCreate) {
5723            return rec;
5724        }
5725        rec = new PendingIntentRecord(this, key, callingUid);
5726        mIntentSenderRecords.put(key, rec.ref);
5727        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5728            if (activity.pendingResults == null) {
5729                activity.pendingResults
5730                        = new HashSet<WeakReference<PendingIntentRecord>>();
5731            }
5732            activity.pendingResults.add(rec.ref);
5733        }
5734        return rec;
5735    }
5736
5737    @Override
5738    public void cancelIntentSender(IIntentSender sender) {
5739        if (!(sender instanceof PendingIntentRecord)) {
5740            return;
5741        }
5742        synchronized(this) {
5743            PendingIntentRecord rec = (PendingIntentRecord)sender;
5744            try {
5745                int uid = AppGlobals.getPackageManager()
5746                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5747                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5748                    String msg = "Permission Denial: cancelIntentSender() from pid="
5749                        + Binder.getCallingPid()
5750                        + ", uid=" + Binder.getCallingUid()
5751                        + " is not allowed to cancel packges "
5752                        + rec.key.packageName;
5753                    Slog.w(TAG, msg);
5754                    throw new SecurityException(msg);
5755                }
5756            } catch (RemoteException e) {
5757                throw new SecurityException(e);
5758            }
5759            cancelIntentSenderLocked(rec, true);
5760        }
5761    }
5762
5763    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5764        rec.canceled = true;
5765        mIntentSenderRecords.remove(rec.key);
5766        if (cleanActivity && rec.key.activity != null) {
5767            rec.key.activity.pendingResults.remove(rec.ref);
5768        }
5769    }
5770
5771    @Override
5772    public String getPackageForIntentSender(IIntentSender pendingResult) {
5773        if (!(pendingResult instanceof PendingIntentRecord)) {
5774            return null;
5775        }
5776        try {
5777            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5778            return res.key.packageName;
5779        } catch (ClassCastException e) {
5780        }
5781        return null;
5782    }
5783
5784    @Override
5785    public int getUidForIntentSender(IIntentSender sender) {
5786        if (sender instanceof PendingIntentRecord) {
5787            try {
5788                PendingIntentRecord res = (PendingIntentRecord)sender;
5789                return res.uid;
5790            } catch (ClassCastException e) {
5791            }
5792        }
5793        return -1;
5794    }
5795
5796    @Override
5797    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5798        if (!(pendingResult instanceof PendingIntentRecord)) {
5799            return false;
5800        }
5801        try {
5802            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5803            if (res.key.allIntents == null) {
5804                return false;
5805            }
5806            for (int i=0; i<res.key.allIntents.length; i++) {
5807                Intent intent = res.key.allIntents[i];
5808                if (intent.getPackage() != null && intent.getComponent() != null) {
5809                    return false;
5810                }
5811            }
5812            return true;
5813        } catch (ClassCastException e) {
5814        }
5815        return false;
5816    }
5817
5818    @Override
5819    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5820        if (!(pendingResult instanceof PendingIntentRecord)) {
5821            return false;
5822        }
5823        try {
5824            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5825            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5826                return true;
5827            }
5828            return false;
5829        } catch (ClassCastException e) {
5830        }
5831        return false;
5832    }
5833
5834    @Override
5835    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5836        if (!(pendingResult instanceof PendingIntentRecord)) {
5837            return null;
5838        }
5839        try {
5840            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5841            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5842        } catch (ClassCastException e) {
5843        }
5844        return null;
5845    }
5846
5847    @Override
5848    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5849        if (!(pendingResult instanceof PendingIntentRecord)) {
5850            return null;
5851        }
5852        try {
5853            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5854            Intent intent = res.key.requestIntent;
5855            if (intent != null) {
5856                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5857                        || res.lastTagPrefix.equals(prefix))) {
5858                    return res.lastTag;
5859                }
5860                res.lastTagPrefix = prefix;
5861                StringBuilder sb = new StringBuilder(128);
5862                if (prefix != null) {
5863                    sb.append(prefix);
5864                }
5865                if (intent.getAction() != null) {
5866                    sb.append(intent.getAction());
5867                } else if (intent.getComponent() != null) {
5868                    intent.getComponent().appendShortString(sb);
5869                } else {
5870                    sb.append("?");
5871                }
5872                return res.lastTag = sb.toString();
5873            }
5874        } catch (ClassCastException e) {
5875        }
5876        return null;
5877    }
5878
5879    @Override
5880    public void setProcessLimit(int max) {
5881        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5882                "setProcessLimit()");
5883        synchronized (this) {
5884            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5885            mProcessLimitOverride = max;
5886        }
5887        trimApplications();
5888    }
5889
5890    @Override
5891    public int getProcessLimit() {
5892        synchronized (this) {
5893            return mProcessLimitOverride;
5894        }
5895    }
5896
5897    void foregroundTokenDied(ForegroundToken token) {
5898        synchronized (ActivityManagerService.this) {
5899            synchronized (mPidsSelfLocked) {
5900                ForegroundToken cur
5901                    = mForegroundProcesses.get(token.pid);
5902                if (cur != token) {
5903                    return;
5904                }
5905                mForegroundProcesses.remove(token.pid);
5906                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5907                if (pr == null) {
5908                    return;
5909                }
5910                pr.forcingToForeground = null;
5911                updateProcessForegroundLocked(pr, false, false);
5912            }
5913            updateOomAdjLocked();
5914        }
5915    }
5916
5917    @Override
5918    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5919        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5920                "setProcessForeground()");
5921        synchronized(this) {
5922            boolean changed = false;
5923
5924            synchronized (mPidsSelfLocked) {
5925                ProcessRecord pr = mPidsSelfLocked.get(pid);
5926                if (pr == null && isForeground) {
5927                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5928                    return;
5929                }
5930                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5931                if (oldToken != null) {
5932                    oldToken.token.unlinkToDeath(oldToken, 0);
5933                    mForegroundProcesses.remove(pid);
5934                    if (pr != null) {
5935                        pr.forcingToForeground = null;
5936                    }
5937                    changed = true;
5938                }
5939                if (isForeground && token != null) {
5940                    ForegroundToken newToken = new ForegroundToken() {
5941                        @Override
5942                        public void binderDied() {
5943                            foregroundTokenDied(this);
5944                        }
5945                    };
5946                    newToken.pid = pid;
5947                    newToken.token = token;
5948                    try {
5949                        token.linkToDeath(newToken, 0);
5950                        mForegroundProcesses.put(pid, newToken);
5951                        pr.forcingToForeground = token;
5952                        changed = true;
5953                    } catch (RemoteException e) {
5954                        // If the process died while doing this, we will later
5955                        // do the cleanup with the process death link.
5956                    }
5957                }
5958            }
5959
5960            if (changed) {
5961                updateOomAdjLocked();
5962            }
5963        }
5964    }
5965
5966    // =========================================================
5967    // PERMISSIONS
5968    // =========================================================
5969
5970    static class PermissionController extends IPermissionController.Stub {
5971        ActivityManagerService mActivityManagerService;
5972        PermissionController(ActivityManagerService activityManagerService) {
5973            mActivityManagerService = activityManagerService;
5974        }
5975
5976        @Override
5977        public boolean checkPermission(String permission, int pid, int uid) {
5978            return mActivityManagerService.checkPermission(permission, pid,
5979                    uid) == PackageManager.PERMISSION_GRANTED;
5980        }
5981    }
5982
5983    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5984        @Override
5985        public int checkComponentPermission(String permission, int pid, int uid,
5986                int owningUid, boolean exported) {
5987            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5988                    owningUid, exported);
5989        }
5990
5991        @Override
5992        public Object getAMSLock() {
5993            return ActivityManagerService.this;
5994        }
5995    }
5996
5997    /**
5998     * This can be called with or without the global lock held.
5999     */
6000    int checkComponentPermission(String permission, int pid, int uid,
6001            int owningUid, boolean exported) {
6002        // We might be performing an operation on behalf of an indirect binder
6003        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6004        // client identity accordingly before proceeding.
6005        Identity tlsIdentity = sCallerIdentity.get();
6006        if (tlsIdentity != null) {
6007            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6008                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6009            uid = tlsIdentity.uid;
6010            pid = tlsIdentity.pid;
6011        }
6012
6013        if (pid == MY_PID) {
6014            return PackageManager.PERMISSION_GRANTED;
6015        }
6016
6017        return ActivityManager.checkComponentPermission(permission, uid,
6018                owningUid, exported);
6019    }
6020
6021    /**
6022     * As the only public entry point for permissions checking, this method
6023     * can enforce the semantic that requesting a check on a null global
6024     * permission is automatically denied.  (Internally a null permission
6025     * string is used when calling {@link #checkComponentPermission} in cases
6026     * when only uid-based security is needed.)
6027     *
6028     * This can be called with or without the global lock held.
6029     */
6030    @Override
6031    public int checkPermission(String permission, int pid, int uid) {
6032        if (permission == null) {
6033            return PackageManager.PERMISSION_DENIED;
6034        }
6035        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6036    }
6037
6038    /**
6039     * Binder IPC calls go through the public entry point.
6040     * This can be called with or without the global lock held.
6041     */
6042    int checkCallingPermission(String permission) {
6043        return checkPermission(permission,
6044                Binder.getCallingPid(),
6045                UserHandle.getAppId(Binder.getCallingUid()));
6046    }
6047
6048    /**
6049     * This can be called with or without the global lock held.
6050     */
6051    void enforceCallingPermission(String permission, String func) {
6052        if (checkCallingPermission(permission)
6053                == PackageManager.PERMISSION_GRANTED) {
6054            return;
6055        }
6056
6057        String msg = "Permission Denial: " + func + " from pid="
6058                + Binder.getCallingPid()
6059                + ", uid=" + Binder.getCallingUid()
6060                + " requires " + permission;
6061        Slog.w(TAG, msg);
6062        throw new SecurityException(msg);
6063    }
6064
6065    /**
6066     * Determine if UID is holding permissions required to access {@link Uri} in
6067     * the given {@link ProviderInfo}. Final permission checking is always done
6068     * in {@link ContentProvider}.
6069     */
6070    private final boolean checkHoldingPermissionsLocked(
6071            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6072        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6073                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6074        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6075            return false;
6076        }
6077
6078        if (pi.applicationInfo.uid == uid) {
6079            return true;
6080        } else if (!pi.exported) {
6081            return false;
6082        }
6083
6084        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6085        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6086        try {
6087            // check if target holds top-level <provider> permissions
6088            if (!readMet && pi.readPermission != null
6089                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6090                readMet = true;
6091            }
6092            if (!writeMet && pi.writePermission != null
6093                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6094                writeMet = true;
6095            }
6096
6097            // track if unprotected read/write is allowed; any denied
6098            // <path-permission> below removes this ability
6099            boolean allowDefaultRead = pi.readPermission == null;
6100            boolean allowDefaultWrite = pi.writePermission == null;
6101
6102            // check if target holds any <path-permission> that match uri
6103            final PathPermission[] pps = pi.pathPermissions;
6104            if (pps != null) {
6105                final String path = grantUri.uri.getPath();
6106                int i = pps.length;
6107                while (i > 0 && (!readMet || !writeMet)) {
6108                    i--;
6109                    PathPermission pp = pps[i];
6110                    if (pp.match(path)) {
6111                        if (!readMet) {
6112                            final String pprperm = pp.getReadPermission();
6113                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6114                                    + pprperm + " for " + pp.getPath()
6115                                    + ": match=" + pp.match(path)
6116                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6117                            if (pprperm != null) {
6118                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6119                                    readMet = true;
6120                                } else {
6121                                    allowDefaultRead = false;
6122                                }
6123                            }
6124                        }
6125                        if (!writeMet) {
6126                            final String ppwperm = pp.getWritePermission();
6127                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6128                                    + ppwperm + " for " + pp.getPath()
6129                                    + ": match=" + pp.match(path)
6130                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6131                            if (ppwperm != null) {
6132                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6133                                    writeMet = true;
6134                                } else {
6135                                    allowDefaultWrite = false;
6136                                }
6137                            }
6138                        }
6139                    }
6140                }
6141            }
6142
6143            // grant unprotected <provider> read/write, if not blocked by
6144            // <path-permission> above
6145            if (allowDefaultRead) readMet = true;
6146            if (allowDefaultWrite) writeMet = true;
6147
6148        } catch (RemoteException e) {
6149            return false;
6150        }
6151
6152        return readMet && writeMet;
6153    }
6154
6155    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6156        ProviderInfo pi = null;
6157        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6158        if (cpr != null) {
6159            pi = cpr.info;
6160        } else {
6161            try {
6162                pi = AppGlobals.getPackageManager().resolveContentProvider(
6163                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6164            } catch (RemoteException ex) {
6165            }
6166        }
6167        return pi;
6168    }
6169
6170    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6171        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6172        if (targetUris != null) {
6173            return targetUris.get(grantUri);
6174        }
6175        return null;
6176    }
6177
6178    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6179            String targetPkg, int targetUid, GrantUri grantUri) {
6180        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6181        if (targetUris == null) {
6182            targetUris = Maps.newArrayMap();
6183            mGrantedUriPermissions.put(targetUid, targetUris);
6184        }
6185
6186        UriPermission perm = targetUris.get(grantUri);
6187        if (perm == null) {
6188            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6189            targetUris.put(grantUri, perm);
6190        }
6191
6192        return perm;
6193    }
6194
6195    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6196            final int modeFlags) {
6197        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6198        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6199                : UriPermission.STRENGTH_OWNED;
6200
6201        // Root gets to do everything.
6202        if (uid == 0) {
6203            return true;
6204        }
6205
6206        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6207        if (perms == null) return false;
6208
6209        // First look for exact match
6210        final UriPermission exactPerm = perms.get(grantUri);
6211        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6212            return true;
6213        }
6214
6215        // No exact match, look for prefixes
6216        final int N = perms.size();
6217        for (int i = 0; i < N; i++) {
6218            final UriPermission perm = perms.valueAt(i);
6219            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6220                    && perm.getStrength(modeFlags) >= minStrength) {
6221                return true;
6222            }
6223        }
6224
6225        return false;
6226    }
6227
6228    @Override
6229    public int checkUriPermission(Uri uri, int pid, int uid,
6230            final int modeFlags, int userId) {
6231        enforceNotIsolatedCaller("checkUriPermission");
6232
6233        // Another redirected-binder-call permissions check as in
6234        // {@link checkComponentPermission}.
6235        Identity tlsIdentity = sCallerIdentity.get();
6236        if (tlsIdentity != null) {
6237            uid = tlsIdentity.uid;
6238            pid = tlsIdentity.pid;
6239        }
6240
6241        // Our own process gets to do everything.
6242        if (pid == MY_PID) {
6243            return PackageManager.PERMISSION_GRANTED;
6244        }
6245        synchronized (this) {
6246            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6247                    ? PackageManager.PERMISSION_GRANTED
6248                    : PackageManager.PERMISSION_DENIED;
6249        }
6250    }
6251
6252    /**
6253     * Check if the targetPkg can be granted permission to access uri by
6254     * the callingUid using the given modeFlags.  Throws a security exception
6255     * if callingUid is not allowed to do this.  Returns the uid of the target
6256     * if the URI permission grant should be performed; returns -1 if it is not
6257     * needed (for example targetPkg already has permission to access the URI).
6258     * If you already know the uid of the target, you can supply it in
6259     * lastTargetUid else set that to -1.
6260     */
6261    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6262            final int modeFlags, int lastTargetUid) {
6263        if (!Intent.isAccessUriMode(modeFlags)) {
6264            return -1;
6265        }
6266
6267        if (targetPkg != null) {
6268            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6269                    "Checking grant " + targetPkg + " permission to " + grantUri);
6270        }
6271
6272        final IPackageManager pm = AppGlobals.getPackageManager();
6273
6274        // If this is not a content: uri, we can't do anything with it.
6275        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6276            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6277                    "Can't grant URI permission for non-content URI: " + grantUri);
6278            return -1;
6279        }
6280
6281        final String authority = grantUri.uri.getAuthority();
6282        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6283        if (pi == null) {
6284            Slog.w(TAG, "No content provider found for permission check: " +
6285                    grantUri.uri.toSafeString());
6286            return -1;
6287        }
6288
6289        int targetUid = lastTargetUid;
6290        if (targetUid < 0 && targetPkg != null) {
6291            try {
6292                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6293                if (targetUid < 0) {
6294                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6295                            "Can't grant URI permission no uid for: " + targetPkg);
6296                    return -1;
6297                }
6298            } catch (RemoteException ex) {
6299                return -1;
6300            }
6301        }
6302
6303        if (targetUid >= 0) {
6304            // First...  does the target actually need this permission?
6305            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6306                // No need to grant the target this permission.
6307                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6308                        "Target " + targetPkg + " already has full permission to " + grantUri);
6309                return -1;
6310            }
6311        } else {
6312            // First...  there is no target package, so can anyone access it?
6313            boolean allowed = pi.exported;
6314            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6315                if (pi.readPermission != null) {
6316                    allowed = false;
6317                }
6318            }
6319            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6320                if (pi.writePermission != null) {
6321                    allowed = false;
6322                }
6323            }
6324            if (allowed) {
6325                return -1;
6326            }
6327        }
6328
6329        // Second...  is the provider allowing granting of URI permissions?
6330        if (!pi.grantUriPermissions) {
6331            throw new SecurityException("Provider " + pi.packageName
6332                    + "/" + pi.name
6333                    + " does not allow granting of Uri permissions (uri "
6334                    + grantUri + ")");
6335        }
6336        if (pi.uriPermissionPatterns != null) {
6337            final int N = pi.uriPermissionPatterns.length;
6338            boolean allowed = false;
6339            for (int i=0; i<N; i++) {
6340                if (pi.uriPermissionPatterns[i] != null
6341                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6342                    allowed = true;
6343                    break;
6344                }
6345            }
6346            if (!allowed) {
6347                throw new SecurityException("Provider " + pi.packageName
6348                        + "/" + pi.name
6349                        + " does not allow granting of permission to path of Uri "
6350                        + grantUri);
6351            }
6352        }
6353
6354        // Third...  does the caller itself have permission to access
6355        // this uri?
6356        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6357            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6358                // Require they hold a strong enough Uri permission
6359                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6360                    throw new SecurityException("Uid " + callingUid
6361                            + " does not have permission to uri " + grantUri);
6362                }
6363            }
6364        }
6365        return targetUid;
6366    }
6367
6368    @Override
6369    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6370            final int modeFlags, int userId) {
6371        enforceNotIsolatedCaller("checkGrantUriPermission");
6372        synchronized(this) {
6373            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6374                    new GrantUri(userId, uri, false), modeFlags, -1);
6375        }
6376    }
6377
6378    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6379            final int modeFlags, UriPermissionOwner owner) {
6380        if (!Intent.isAccessUriMode(modeFlags)) {
6381            return;
6382        }
6383
6384        // So here we are: the caller has the assumed permission
6385        // to the uri, and the target doesn't.  Let's now give this to
6386        // the target.
6387
6388        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6389                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6390
6391        final String authority = grantUri.uri.getAuthority();
6392        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6393        if (pi == null) {
6394            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6395            return;
6396        }
6397
6398        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6399            grantUri.prefix = true;
6400        }
6401        final UriPermission perm = findOrCreateUriPermissionLocked(
6402                pi.packageName, targetPkg, targetUid, grantUri);
6403        perm.grantModes(modeFlags, owner);
6404    }
6405
6406    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6407            final int modeFlags, UriPermissionOwner owner) {
6408        if (targetPkg == null) {
6409            throw new NullPointerException("targetPkg");
6410        }
6411
6412        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6413                -1);
6414        if (targetUid < 0) {
6415            return;
6416        }
6417
6418        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6419                owner);
6420    }
6421
6422    static class NeededUriGrants extends ArrayList<GrantUri> {
6423        final String targetPkg;
6424        final int targetUid;
6425        final int flags;
6426
6427        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6428            this.targetPkg = targetPkg;
6429            this.targetUid = targetUid;
6430            this.flags = flags;
6431        }
6432    }
6433
6434    /**
6435     * Like checkGrantUriPermissionLocked, but takes an Intent.
6436     */
6437    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6438            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6439        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6440                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6441                + " clip=" + (intent != null ? intent.getClipData() : null)
6442                + " from " + intent + "; flags=0x"
6443                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6444
6445        if (targetPkg == null) {
6446            throw new NullPointerException("targetPkg");
6447        }
6448
6449        if (intent == null) {
6450            return null;
6451        }
6452        Uri data = intent.getData();
6453        ClipData clip = intent.getClipData();
6454        if (data == null && clip == null) {
6455            return null;
6456        }
6457        final IPackageManager pm = AppGlobals.getPackageManager();
6458        int targetUid;
6459        if (needed != null) {
6460            targetUid = needed.targetUid;
6461        } else {
6462            try {
6463                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6464            } catch (RemoteException ex) {
6465                return null;
6466            }
6467            if (targetUid < 0) {
6468                if (DEBUG_URI_PERMISSION) {
6469                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6470                            + " on user " + targetUserId);
6471                }
6472                return null;
6473            }
6474        }
6475        if (data != null) {
6476            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6477            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6478                    targetUid);
6479            if (targetUid > 0) {
6480                if (needed == null) {
6481                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6482                }
6483                needed.add(grantUri);
6484            }
6485        }
6486        if (clip != null) {
6487            for (int i=0; i<clip.getItemCount(); i++) {
6488                Uri uri = clip.getItemAt(i).getUri();
6489                if (uri != null) {
6490                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6491                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6492                            targetUid);
6493                    if (targetUid > 0) {
6494                        if (needed == null) {
6495                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6496                        }
6497                        needed.add(grantUri);
6498                    }
6499                } else {
6500                    Intent clipIntent = clip.getItemAt(i).getIntent();
6501                    if (clipIntent != null) {
6502                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6503                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6504                        if (newNeeded != null) {
6505                            needed = newNeeded;
6506                        }
6507                    }
6508                }
6509            }
6510        }
6511
6512        return needed;
6513    }
6514
6515    /**
6516     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6517     */
6518    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6519            UriPermissionOwner owner) {
6520        if (needed != null) {
6521            for (int i=0; i<needed.size(); i++) {
6522                GrantUri grantUri = needed.get(i);
6523                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6524                        grantUri, needed.flags, owner);
6525            }
6526        }
6527    }
6528
6529    void grantUriPermissionFromIntentLocked(int callingUid,
6530            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6531        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6532                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6533        if (needed == null) {
6534            return;
6535        }
6536
6537        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6538    }
6539
6540    @Override
6541    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6542            final int modeFlags, int userId) {
6543        enforceNotIsolatedCaller("grantUriPermission");
6544        GrantUri grantUri = new GrantUri(userId, uri, false);
6545        synchronized(this) {
6546            final ProcessRecord r = getRecordForAppLocked(caller);
6547            if (r == null) {
6548                throw new SecurityException("Unable to find app for caller "
6549                        + caller
6550                        + " when granting permission to uri " + grantUri);
6551            }
6552            if (targetPkg == null) {
6553                throw new IllegalArgumentException("null target");
6554            }
6555            if (grantUri == null) {
6556                throw new IllegalArgumentException("null uri");
6557            }
6558
6559            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6560                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6561                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6562                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6563
6564            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6565        }
6566    }
6567
6568    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6569        if (perm.modeFlags == 0) {
6570            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6571                    perm.targetUid);
6572            if (perms != null) {
6573                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6574                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6575
6576                perms.remove(perm.uri);
6577                if (perms.isEmpty()) {
6578                    mGrantedUriPermissions.remove(perm.targetUid);
6579                }
6580            }
6581        }
6582    }
6583
6584    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6585        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6586
6587        final IPackageManager pm = AppGlobals.getPackageManager();
6588        final String authority = grantUri.uri.getAuthority();
6589        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6590        if (pi == null) {
6591            Slog.w(TAG, "No content provider found for permission revoke: "
6592                    + grantUri.toSafeString());
6593            return;
6594        }
6595
6596        // Does the caller have this permission on the URI?
6597        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6598            // Right now, if you are not the original owner of the permission,
6599            // you are not allowed to revoke it.
6600            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6601                throw new SecurityException("Uid " + callingUid
6602                        + " does not have permission to uri " + grantUri);
6603            //}
6604        }
6605
6606        boolean persistChanged = false;
6607
6608        // Go through all of the permissions and remove any that match.
6609        int N = mGrantedUriPermissions.size();
6610        for (int i = 0; i < N; i++) {
6611            final int targetUid = mGrantedUriPermissions.keyAt(i);
6612            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6613
6614            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6615                final UriPermission perm = it.next();
6616                if (perm.uri.sourceUserId == grantUri.sourceUserId
6617                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6618                    if (DEBUG_URI_PERMISSION)
6619                        Slog.v(TAG,
6620                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6621                    persistChanged |= perm.revokeModes(
6622                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6623                    if (perm.modeFlags == 0) {
6624                        it.remove();
6625                    }
6626                }
6627            }
6628
6629            if (perms.isEmpty()) {
6630                mGrantedUriPermissions.remove(targetUid);
6631                N--;
6632                i--;
6633            }
6634        }
6635
6636        if (persistChanged) {
6637            schedulePersistUriGrants();
6638        }
6639    }
6640
6641    @Override
6642    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6643            int userId) {
6644        enforceNotIsolatedCaller("revokeUriPermission");
6645        synchronized(this) {
6646            final ProcessRecord r = getRecordForAppLocked(caller);
6647            if (r == null) {
6648                throw new SecurityException("Unable to find app for caller "
6649                        + caller
6650                        + " when revoking permission to uri " + uri);
6651            }
6652            if (uri == null) {
6653                Slog.w(TAG, "revokeUriPermission: null uri");
6654                return;
6655            }
6656
6657            if (!Intent.isAccessUriMode(modeFlags)) {
6658                return;
6659            }
6660
6661            final IPackageManager pm = AppGlobals.getPackageManager();
6662            final String authority = uri.getAuthority();
6663            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6664            if (pi == null) {
6665                Slog.w(TAG, "No content provider found for permission revoke: "
6666                        + uri.toSafeString());
6667                return;
6668            }
6669
6670            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6671        }
6672    }
6673
6674    /**
6675     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6676     * given package.
6677     *
6678     * @param packageName Package name to match, or {@code null} to apply to all
6679     *            packages.
6680     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6681     *            to all users.
6682     * @param persistable If persistable grants should be removed.
6683     */
6684    private void removeUriPermissionsForPackageLocked(
6685            String packageName, int userHandle, boolean persistable) {
6686        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6687            throw new IllegalArgumentException("Must narrow by either package or user");
6688        }
6689
6690        boolean persistChanged = false;
6691
6692        int N = mGrantedUriPermissions.size();
6693        for (int i = 0; i < N; i++) {
6694            final int targetUid = mGrantedUriPermissions.keyAt(i);
6695            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6696
6697            // Only inspect grants matching user
6698            if (userHandle == UserHandle.USER_ALL
6699                    || userHandle == UserHandle.getUserId(targetUid)) {
6700                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6701                    final UriPermission perm = it.next();
6702
6703                    // Only inspect grants matching package
6704                    if (packageName == null || perm.sourcePkg.equals(packageName)
6705                            || perm.targetPkg.equals(packageName)) {
6706                        persistChanged |= perm.revokeModes(
6707                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6708
6709                        // Only remove when no modes remain; any persisted grants
6710                        // will keep this alive.
6711                        if (perm.modeFlags == 0) {
6712                            it.remove();
6713                        }
6714                    }
6715                }
6716
6717                if (perms.isEmpty()) {
6718                    mGrantedUriPermissions.remove(targetUid);
6719                    N--;
6720                    i--;
6721                }
6722            }
6723        }
6724
6725        if (persistChanged) {
6726            schedulePersistUriGrants();
6727        }
6728    }
6729
6730    @Override
6731    public IBinder newUriPermissionOwner(String name) {
6732        enforceNotIsolatedCaller("newUriPermissionOwner");
6733        synchronized(this) {
6734            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6735            return owner.getExternalTokenLocked();
6736        }
6737    }
6738
6739    @Override
6740    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6741            final int modeFlags, int userId) {
6742        synchronized(this) {
6743            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6744            if (owner == null) {
6745                throw new IllegalArgumentException("Unknown owner: " + token);
6746            }
6747            if (fromUid != Binder.getCallingUid()) {
6748                if (Binder.getCallingUid() != Process.myUid()) {
6749                    // Only system code can grant URI permissions on behalf
6750                    // of other users.
6751                    throw new SecurityException("nice try");
6752                }
6753            }
6754            if (targetPkg == null) {
6755                throw new IllegalArgumentException("null target");
6756            }
6757            if (uri == null) {
6758                throw new IllegalArgumentException("null uri");
6759            }
6760
6761            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6762                    modeFlags, owner);
6763        }
6764    }
6765
6766    @Override
6767    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6768        synchronized(this) {
6769            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6770            if (owner == null) {
6771                throw new IllegalArgumentException("Unknown owner: " + token);
6772            }
6773
6774            if (uri == null) {
6775                owner.removeUriPermissionsLocked(mode);
6776            } else {
6777                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6778            }
6779        }
6780    }
6781
6782    private void schedulePersistUriGrants() {
6783        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6784            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6785                    10 * DateUtils.SECOND_IN_MILLIS);
6786        }
6787    }
6788
6789    private void writeGrantedUriPermissions() {
6790        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6791
6792        // Snapshot permissions so we can persist without lock
6793        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6794        synchronized (this) {
6795            final int size = mGrantedUriPermissions.size();
6796            for (int i = 0; i < size; i++) {
6797                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6798                for (UriPermission perm : perms.values()) {
6799                    if (perm.persistedModeFlags != 0) {
6800                        persist.add(perm.snapshot());
6801                    }
6802                }
6803            }
6804        }
6805
6806        FileOutputStream fos = null;
6807        try {
6808            fos = mGrantFile.startWrite();
6809
6810            XmlSerializer out = new FastXmlSerializer();
6811            out.setOutput(fos, "utf-8");
6812            out.startDocument(null, true);
6813            out.startTag(null, TAG_URI_GRANTS);
6814            for (UriPermission.Snapshot perm : persist) {
6815                out.startTag(null, TAG_URI_GRANT);
6816                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6817                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6818                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6819                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6820                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6821                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6822                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6823                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6824                out.endTag(null, TAG_URI_GRANT);
6825            }
6826            out.endTag(null, TAG_URI_GRANTS);
6827            out.endDocument();
6828
6829            mGrantFile.finishWrite(fos);
6830        } catch (IOException e) {
6831            if (fos != null) {
6832                mGrantFile.failWrite(fos);
6833            }
6834        }
6835    }
6836
6837    private void readGrantedUriPermissionsLocked() {
6838        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6839
6840        final long now = System.currentTimeMillis();
6841
6842        FileInputStream fis = null;
6843        try {
6844            fis = mGrantFile.openRead();
6845            final XmlPullParser in = Xml.newPullParser();
6846            in.setInput(fis, null);
6847
6848            int type;
6849            while ((type = in.next()) != END_DOCUMENT) {
6850                final String tag = in.getName();
6851                if (type == START_TAG) {
6852                    if (TAG_URI_GRANT.equals(tag)) {
6853                        final int sourceUserId;
6854                        final int targetUserId;
6855                        final int userHandle = readIntAttribute(in,
6856                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6857                        if (userHandle != UserHandle.USER_NULL) {
6858                            // For backwards compatibility.
6859                            sourceUserId = userHandle;
6860                            targetUserId = userHandle;
6861                        } else {
6862                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6863                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6864                        }
6865                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6866                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6867                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6868                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6869                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6870                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6871
6872                        // Sanity check that provider still belongs to source package
6873                        final ProviderInfo pi = getProviderInfoLocked(
6874                                uri.getAuthority(), sourceUserId);
6875                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6876                            int targetUid = -1;
6877                            try {
6878                                targetUid = AppGlobals.getPackageManager()
6879                                        .getPackageUid(targetPkg, targetUserId);
6880                            } catch (RemoteException e) {
6881                            }
6882                            if (targetUid != -1) {
6883                                final UriPermission perm = findOrCreateUriPermissionLocked(
6884                                        sourcePkg, targetPkg, targetUid,
6885                                        new GrantUri(sourceUserId, uri, prefix));
6886                                perm.initPersistedModes(modeFlags, createdTime);
6887                            }
6888                        } else {
6889                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6890                                    + " but instead found " + pi);
6891                        }
6892                    }
6893                }
6894            }
6895        } catch (FileNotFoundException e) {
6896            // Missing grants is okay
6897        } catch (IOException e) {
6898            Log.wtf(TAG, "Failed reading Uri grants", e);
6899        } catch (XmlPullParserException e) {
6900            Log.wtf(TAG, "Failed reading Uri grants", e);
6901        } finally {
6902            IoUtils.closeQuietly(fis);
6903        }
6904    }
6905
6906    @Override
6907    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6908        enforceNotIsolatedCaller("takePersistableUriPermission");
6909
6910        Preconditions.checkFlagsArgument(modeFlags,
6911                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6912
6913        synchronized (this) {
6914            final int callingUid = Binder.getCallingUid();
6915            boolean persistChanged = false;
6916            GrantUri grantUri = new GrantUri(userId, uri, false);
6917
6918            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6919                    new GrantUri(userId, uri, false));
6920            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6921                    new GrantUri(userId, uri, true));
6922
6923            final boolean exactValid = (exactPerm != null)
6924                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6925            final boolean prefixValid = (prefixPerm != null)
6926                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6927
6928            if (!(exactValid || prefixValid)) {
6929                throw new SecurityException("No persistable permission grants found for UID "
6930                        + callingUid + " and Uri " + grantUri.toSafeString());
6931            }
6932
6933            if (exactValid) {
6934                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6935            }
6936            if (prefixValid) {
6937                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6938            }
6939
6940            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6941
6942            if (persistChanged) {
6943                schedulePersistUriGrants();
6944            }
6945        }
6946    }
6947
6948    @Override
6949    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6950        enforceNotIsolatedCaller("releasePersistableUriPermission");
6951
6952        Preconditions.checkFlagsArgument(modeFlags,
6953                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6954
6955        synchronized (this) {
6956            final int callingUid = Binder.getCallingUid();
6957            boolean persistChanged = false;
6958
6959            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6960                    new GrantUri(userId, uri, false));
6961            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6962                    new GrantUri(userId, uri, true));
6963            if (exactPerm == null && prefixPerm == null) {
6964                throw new SecurityException("No permission grants found for UID " + callingUid
6965                        + " and Uri " + uri.toSafeString());
6966            }
6967
6968            if (exactPerm != null) {
6969                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6970                removeUriPermissionIfNeededLocked(exactPerm);
6971            }
6972            if (prefixPerm != null) {
6973                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6974                removeUriPermissionIfNeededLocked(prefixPerm);
6975            }
6976
6977            if (persistChanged) {
6978                schedulePersistUriGrants();
6979            }
6980        }
6981    }
6982
6983    /**
6984     * Prune any older {@link UriPermission} for the given UID until outstanding
6985     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6986     *
6987     * @return if any mutations occured that require persisting.
6988     */
6989    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6990        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6991        if (perms == null) return false;
6992        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6993
6994        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6995        for (UriPermission perm : perms.values()) {
6996            if (perm.persistedModeFlags != 0) {
6997                persisted.add(perm);
6998            }
6999        }
7000
7001        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7002        if (trimCount <= 0) return false;
7003
7004        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7005        for (int i = 0; i < trimCount; i++) {
7006            final UriPermission perm = persisted.get(i);
7007
7008            if (DEBUG_URI_PERMISSION) {
7009                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7010            }
7011
7012            perm.releasePersistableModes(~0);
7013            removeUriPermissionIfNeededLocked(perm);
7014        }
7015
7016        return true;
7017    }
7018
7019    @Override
7020    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7021            String packageName, boolean incoming) {
7022        enforceNotIsolatedCaller("getPersistedUriPermissions");
7023        Preconditions.checkNotNull(packageName, "packageName");
7024
7025        final int callingUid = Binder.getCallingUid();
7026        final IPackageManager pm = AppGlobals.getPackageManager();
7027        try {
7028            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7029            if (packageUid != callingUid) {
7030                throw new SecurityException(
7031                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7032            }
7033        } catch (RemoteException e) {
7034            throw new SecurityException("Failed to verify package name ownership");
7035        }
7036
7037        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7038        synchronized (this) {
7039            if (incoming) {
7040                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7041                        callingUid);
7042                if (perms == null) {
7043                    Slog.w(TAG, "No permission grants found for " + packageName);
7044                } else {
7045                    for (UriPermission perm : perms.values()) {
7046                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7047                            result.add(perm.buildPersistedPublicApiObject());
7048                        }
7049                    }
7050                }
7051            } else {
7052                final int size = mGrantedUriPermissions.size();
7053                for (int i = 0; i < size; i++) {
7054                    final ArrayMap<GrantUri, UriPermission> perms =
7055                            mGrantedUriPermissions.valueAt(i);
7056                    for (UriPermission perm : perms.values()) {
7057                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7058                            result.add(perm.buildPersistedPublicApiObject());
7059                        }
7060                    }
7061                }
7062            }
7063        }
7064        return new ParceledListSlice<android.content.UriPermission>(result);
7065    }
7066
7067    @Override
7068    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7069        synchronized (this) {
7070            ProcessRecord app =
7071                who != null ? getRecordForAppLocked(who) : null;
7072            if (app == null) return;
7073
7074            Message msg = Message.obtain();
7075            msg.what = WAIT_FOR_DEBUGGER_MSG;
7076            msg.obj = app;
7077            msg.arg1 = waiting ? 1 : 0;
7078            mHandler.sendMessage(msg);
7079        }
7080    }
7081
7082    @Override
7083    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7084        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7085        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7086        outInfo.availMem = Process.getFreeMemory();
7087        outInfo.totalMem = Process.getTotalMemory();
7088        outInfo.threshold = homeAppMem;
7089        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7090        outInfo.hiddenAppThreshold = cachedAppMem;
7091        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7092                ProcessList.SERVICE_ADJ);
7093        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7094                ProcessList.VISIBLE_APP_ADJ);
7095        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7096                ProcessList.FOREGROUND_APP_ADJ);
7097    }
7098
7099    // =========================================================
7100    // TASK MANAGEMENT
7101    // =========================================================
7102
7103    @Override
7104    public List<IAppTask> getAppTasks() {
7105        int callingUid = Binder.getCallingUid();
7106        long ident = Binder.clearCallingIdentity();
7107        synchronized(this) {
7108            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7109            try {
7110                if (localLOGV) Slog.v(TAG, "getAppTasks");
7111
7112                final int N = mRecentTasks.size();
7113                for (int i = 0; i < N; i++) {
7114                    TaskRecord tr = mRecentTasks.get(i);
7115                    // Skip tasks that are not created by the caller
7116                    if (tr.creatorUid == callingUid) {
7117                        ActivityManager.RecentTaskInfo taskInfo =
7118                                createRecentTaskInfoFromTaskRecord(tr);
7119                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7120                        list.add(taskImpl);
7121                    }
7122                }
7123            } finally {
7124                Binder.restoreCallingIdentity(ident);
7125            }
7126            return list;
7127        }
7128    }
7129
7130    @Override
7131    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7132        final int callingUid = Binder.getCallingUid();
7133        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7134
7135        synchronized(this) {
7136            if (localLOGV) Slog.v(
7137                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7138
7139            final boolean allowed = checkCallingPermission(
7140                    android.Manifest.permission.GET_TASKS)
7141                    == PackageManager.PERMISSION_GRANTED;
7142            if (!allowed) {
7143                Slog.w(TAG, "getTasks: caller " + callingUid
7144                        + " does not hold GET_TASKS; limiting output");
7145            }
7146
7147            // TODO: Improve with MRU list from all ActivityStacks.
7148            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7149        }
7150
7151        return list;
7152    }
7153
7154    TaskRecord getMostRecentTask() {
7155        return mRecentTasks.get(0);
7156    }
7157
7158    /**
7159     * Creates a new RecentTaskInfo from a TaskRecord.
7160     */
7161    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7162        // Update the task description to reflect any changes in the task stack
7163        tr.updateTaskDescription();
7164
7165        // Compose the recent task info
7166        ActivityManager.RecentTaskInfo rti
7167                = new ActivityManager.RecentTaskInfo();
7168        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7169        rti.persistentId = tr.taskId;
7170        rti.baseIntent = new Intent(tr.getBaseIntent());
7171        rti.origActivity = tr.origActivity;
7172        rti.description = tr.lastDescription;
7173        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7174        rti.userId = tr.userId;
7175        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7176        return rti;
7177    }
7178
7179    @Override
7180    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7181            int flags, int userId) {
7182        final int callingUid = Binder.getCallingUid();
7183        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7184                false, true, "getRecentTasks", null);
7185
7186        synchronized (this) {
7187            final boolean allowed = checkCallingPermission(
7188                    android.Manifest.permission.GET_TASKS)
7189                    == PackageManager.PERMISSION_GRANTED;
7190            if (!allowed) {
7191                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7192                        + " does not hold GET_TASKS; limiting output");
7193            }
7194            final boolean detailed = checkCallingPermission(
7195                    android.Manifest.permission.GET_DETAILED_TASKS)
7196                    == PackageManager.PERMISSION_GRANTED;
7197
7198            IPackageManager pm = AppGlobals.getPackageManager();
7199
7200            final int N = mRecentTasks.size();
7201            ArrayList<ActivityManager.RecentTaskInfo> res
7202                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7203                            maxNum < N ? maxNum : N);
7204
7205            final Set<Integer> includedUsers;
7206            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7207                includedUsers = getProfileIdsLocked(userId);
7208            } else {
7209                includedUsers = new HashSet<Integer>();
7210            }
7211            includedUsers.add(Integer.valueOf(userId));
7212            for (int i=0; i<N && maxNum > 0; i++) {
7213                TaskRecord tr = mRecentTasks.get(i);
7214                // Only add calling user or related users recent tasks
7215                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7216
7217                // Return the entry if desired by the caller.  We always return
7218                // the first entry, because callers always expect this to be the
7219                // foreground app.  We may filter others if the caller has
7220                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7221                // we should exclude the entry.
7222
7223                if (i == 0
7224                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7225                        || (tr.intent == null)
7226                        || ((tr.intent.getFlags()
7227                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7228                    if (!allowed) {
7229                        // If the caller doesn't have the GET_TASKS permission, then only
7230                        // allow them to see a small subset of tasks -- their own and home.
7231                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7232                            continue;
7233                        }
7234                    }
7235
7236                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7237                    if (!detailed) {
7238                        rti.baseIntent.replaceExtras((Bundle)null);
7239                    }
7240
7241                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7242                        // Check whether this activity is currently available.
7243                        try {
7244                            if (rti.origActivity != null) {
7245                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7246                                        == null) {
7247                                    continue;
7248                                }
7249                            } else if (rti.baseIntent != null) {
7250                                if (pm.queryIntentActivities(rti.baseIntent,
7251                                        null, 0, userId) == null) {
7252                                    continue;
7253                                }
7254                            }
7255                        } catch (RemoteException e) {
7256                            // Will never happen.
7257                        }
7258                    }
7259
7260                    res.add(rti);
7261                    maxNum--;
7262                }
7263            }
7264            return res;
7265        }
7266    }
7267
7268    private TaskRecord recentTaskForIdLocked(int id) {
7269        final int N = mRecentTasks.size();
7270            for (int i=0; i<N; i++) {
7271                TaskRecord tr = mRecentTasks.get(i);
7272                if (tr.taskId == id) {
7273                    return tr;
7274                }
7275            }
7276            return null;
7277    }
7278
7279    @Override
7280    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7281        synchronized (this) {
7282            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7283                    "getTaskThumbnails()");
7284            TaskRecord tr = recentTaskForIdLocked(id);
7285            if (tr != null) {
7286                return tr.getTaskThumbnailsLocked();
7287            }
7288        }
7289        return null;
7290    }
7291
7292    @Override
7293    public Bitmap getTaskTopThumbnail(int id) {
7294        synchronized (this) {
7295            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7296                    "getTaskTopThumbnail()");
7297            TaskRecord tr = recentTaskForIdLocked(id);
7298            if (tr != null) {
7299                return tr.getTaskTopThumbnailLocked();
7300            }
7301        }
7302        return null;
7303    }
7304
7305    @Override
7306    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7307        synchronized (this) {
7308            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7309            if (r != null) {
7310                r.taskDescription = td;
7311                r.task.updateTaskDescription();
7312            }
7313        }
7314    }
7315
7316    @Override
7317    public boolean removeSubTask(int taskId, int subTaskIndex) {
7318        synchronized (this) {
7319            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7320                    "removeSubTask()");
7321            long ident = Binder.clearCallingIdentity();
7322            try {
7323                TaskRecord tr = recentTaskForIdLocked(taskId);
7324                if (tr != null) {
7325                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7326                }
7327                return false;
7328            } finally {
7329                Binder.restoreCallingIdentity(ident);
7330            }
7331        }
7332    }
7333
7334    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7335        if (!pr.killedByAm) {
7336            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7337            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7338                    pr.processName, pr.setAdj, reason);
7339            pr.killedByAm = true;
7340            Process.killProcessQuiet(pr.pid);
7341        }
7342    }
7343
7344    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7345        tr.disposeThumbnail();
7346        mRecentTasks.remove(tr);
7347        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7348        Intent baseIntent = new Intent(
7349                tr.intent != null ? tr.intent : tr.affinityIntent);
7350        ComponentName component = baseIntent.getComponent();
7351        if (component == null) {
7352            Slog.w(TAG, "Now component for base intent of task: " + tr);
7353            return;
7354        }
7355
7356        // Find any running services associated with this app.
7357        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7358
7359        if (killProcesses) {
7360            // Find any running processes associated with this app.
7361            final String pkg = component.getPackageName();
7362            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7363            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7364            for (int i=0; i<pmap.size(); i++) {
7365                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7366                for (int j=0; j<uids.size(); j++) {
7367                    ProcessRecord proc = uids.valueAt(j);
7368                    if (proc.userId != tr.userId) {
7369                        continue;
7370                    }
7371                    if (!proc.pkgList.containsKey(pkg)) {
7372                        continue;
7373                    }
7374                    procs.add(proc);
7375                }
7376            }
7377
7378            // Kill the running processes.
7379            for (int i=0; i<procs.size(); i++) {
7380                ProcessRecord pr = procs.get(i);
7381                if (pr == mHomeProcess) {
7382                    // Don't kill the home process along with tasks from the same package.
7383                    continue;
7384                }
7385                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7386                    killUnneededProcessLocked(pr, "remove task");
7387                } else {
7388                    pr.waitingToKill = "remove task";
7389                }
7390            }
7391        }
7392    }
7393
7394    /**
7395     * Removes the task with the specified task id.
7396     *
7397     * @param taskId Identifier of the task to be removed.
7398     * @param flags Additional operational flags.  May be 0 or
7399     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7400     * @return Returns true if the given task was found and removed.
7401     */
7402    private boolean removeTaskByIdLocked(int taskId, int flags) {
7403        TaskRecord tr = recentTaskForIdLocked(taskId);
7404        if (tr != null) {
7405            tr.removeTaskActivitiesLocked(-1, false);
7406            cleanUpRemovedTaskLocked(tr, flags);
7407            if (tr.isPersistable) {
7408                notifyTaskPersisterLocked(tr, true);
7409            }
7410            return true;
7411        }
7412        return false;
7413    }
7414
7415    @Override
7416    public boolean removeTask(int taskId, int flags) {
7417        synchronized (this) {
7418            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7419                    "removeTask()");
7420            long ident = Binder.clearCallingIdentity();
7421            try {
7422                return removeTaskByIdLocked(taskId, flags);
7423            } finally {
7424                Binder.restoreCallingIdentity(ident);
7425            }
7426        }
7427    }
7428
7429    /**
7430     * TODO: Add mController hook
7431     */
7432    @Override
7433    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7434        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7435                "moveTaskToFront()");
7436
7437        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7438        synchronized(this) {
7439            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7440                    Binder.getCallingUid(), "Task to front")) {
7441                ActivityOptions.abort(options);
7442                return;
7443            }
7444            final long origId = Binder.clearCallingIdentity();
7445            try {
7446                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7447                if (task == null) {
7448                    return;
7449                }
7450                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7451                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7452                    return;
7453                }
7454                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7455            } finally {
7456                Binder.restoreCallingIdentity(origId);
7457            }
7458            ActivityOptions.abort(options);
7459        }
7460    }
7461
7462    @Override
7463    public void moveTaskToBack(int taskId) {
7464        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7465                "moveTaskToBack()");
7466
7467        synchronized(this) {
7468            TaskRecord tr = recentTaskForIdLocked(taskId);
7469            if (tr != null) {
7470                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7471                ActivityStack stack = tr.stack;
7472                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7473                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7474                            Binder.getCallingUid(), "Task to back")) {
7475                        return;
7476                    }
7477                }
7478                final long origId = Binder.clearCallingIdentity();
7479                try {
7480                    stack.moveTaskToBackLocked(taskId, null);
7481                } finally {
7482                    Binder.restoreCallingIdentity(origId);
7483                }
7484            }
7485        }
7486    }
7487
7488    /**
7489     * Moves an activity, and all of the other activities within the same task, to the bottom
7490     * of the history stack.  The activity's order within the task is unchanged.
7491     *
7492     * @param token A reference to the activity we wish to move
7493     * @param nonRoot If false then this only works if the activity is the root
7494     *                of a task; if true it will work for any activity in a task.
7495     * @return Returns true if the move completed, false if not.
7496     */
7497    @Override
7498    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7499        enforceNotIsolatedCaller("moveActivityTaskToBack");
7500        synchronized(this) {
7501            final long origId = Binder.clearCallingIdentity();
7502            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7503            if (taskId >= 0) {
7504                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7505            }
7506            Binder.restoreCallingIdentity(origId);
7507        }
7508        return false;
7509    }
7510
7511    @Override
7512    public void moveTaskBackwards(int task) {
7513        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7514                "moveTaskBackwards()");
7515
7516        synchronized(this) {
7517            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7518                    Binder.getCallingUid(), "Task backwards")) {
7519                return;
7520            }
7521            final long origId = Binder.clearCallingIdentity();
7522            moveTaskBackwardsLocked(task);
7523            Binder.restoreCallingIdentity(origId);
7524        }
7525    }
7526
7527    private final void moveTaskBackwardsLocked(int task) {
7528        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7529    }
7530
7531    @Override
7532    public IBinder getHomeActivityToken() throws RemoteException {
7533        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7534                "getHomeActivityToken()");
7535        synchronized (this) {
7536            return mStackSupervisor.getHomeActivityToken();
7537        }
7538    }
7539
7540    @Override
7541    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7542            IActivityContainerCallback callback) throws RemoteException {
7543        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7544                "createActivityContainer()");
7545        synchronized (this) {
7546            if (parentActivityToken == null) {
7547                throw new IllegalArgumentException("parent token must not be null");
7548            }
7549            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7550            if (r == null) {
7551                return null;
7552            }
7553            if (callback == null) {
7554                throw new IllegalArgumentException("callback must not be null");
7555            }
7556            return mStackSupervisor.createActivityContainer(r, callback);
7557        }
7558    }
7559
7560    @Override
7561    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7562        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7563                "deleteActivityContainer()");
7564        synchronized (this) {
7565            mStackSupervisor.deleteActivityContainer(container);
7566        }
7567    }
7568
7569    @Override
7570    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7571            throws RemoteException {
7572        synchronized (this) {
7573            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7574            if (stack != null) {
7575                return stack.mActivityContainer;
7576            }
7577            return null;
7578        }
7579    }
7580
7581    @Override
7582    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7583        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7584                "moveTaskToStack()");
7585        if (stackId == HOME_STACK_ID) {
7586            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7587                    new RuntimeException("here").fillInStackTrace());
7588        }
7589        synchronized (this) {
7590            long ident = Binder.clearCallingIdentity();
7591            try {
7592                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7593                        + stackId + " toTop=" + toTop);
7594                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7595            } finally {
7596                Binder.restoreCallingIdentity(ident);
7597            }
7598        }
7599    }
7600
7601    @Override
7602    public void resizeStack(int stackBoxId, Rect bounds) {
7603        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7604                "resizeStackBox()");
7605        long ident = Binder.clearCallingIdentity();
7606        try {
7607            mWindowManager.resizeStack(stackBoxId, bounds);
7608        } finally {
7609            Binder.restoreCallingIdentity(ident);
7610        }
7611    }
7612
7613    @Override
7614    public List<StackInfo> getAllStackInfos() {
7615        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7616                "getAllStackInfos()");
7617        long ident = Binder.clearCallingIdentity();
7618        try {
7619            synchronized (this) {
7620                return mStackSupervisor.getAllStackInfosLocked();
7621            }
7622        } finally {
7623            Binder.restoreCallingIdentity(ident);
7624        }
7625    }
7626
7627    @Override
7628    public StackInfo getStackInfo(int stackId) {
7629        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7630                "getStackInfo()");
7631        long ident = Binder.clearCallingIdentity();
7632        try {
7633            synchronized (this) {
7634                return mStackSupervisor.getStackInfoLocked(stackId);
7635            }
7636        } finally {
7637            Binder.restoreCallingIdentity(ident);
7638        }
7639    }
7640
7641    @Override
7642    public boolean isInHomeStack(int taskId) {
7643        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7644                "getStackInfo()");
7645        long ident = Binder.clearCallingIdentity();
7646        try {
7647            synchronized (this) {
7648                TaskRecord tr = recentTaskForIdLocked(taskId);
7649                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7650            }
7651        } finally {
7652            Binder.restoreCallingIdentity(ident);
7653        }
7654    }
7655
7656    @Override
7657    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7658        synchronized(this) {
7659            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7660        }
7661    }
7662
7663    private boolean isLockTaskAuthorized(String pkg) {
7664        final DevicePolicyManager dpm = (DevicePolicyManager)
7665                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7666        try {
7667            int uid = mContext.getPackageManager().getPackageUid(pkg,
7668                    Binder.getCallingUserHandle().getIdentifier());
7669            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7670        } catch (NameNotFoundException e) {
7671            return false;
7672        }
7673    }
7674
7675    void startLockTaskMode(TaskRecord task) {
7676        final String pkg;
7677        synchronized (this) {
7678            pkg = task.intent.getComponent().getPackageName();
7679        }
7680        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7681        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7682            final TaskRecord taskRecord = task;
7683            mHandler.post(new Runnable() {
7684                @Override
7685                public void run() {
7686                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7687                }
7688            });
7689            return;
7690        }
7691        long ident = Binder.clearCallingIdentity();
7692        try {
7693            synchronized (this) {
7694                // Since we lost lock on task, make sure it is still there.
7695                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7696                if (task != null) {
7697                    if ((mFocusedActivity == null) || (task != mFocusedActivity.task)) {
7698                        throw new IllegalArgumentException("Invalid task, not in foreground");
7699                    }
7700                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
7701                }
7702            }
7703        } finally {
7704            Binder.restoreCallingIdentity(ident);
7705        }
7706    }
7707
7708    @Override
7709    public void startLockTaskMode(int taskId) {
7710        final TaskRecord task;
7711        long ident = Binder.clearCallingIdentity();
7712        try {
7713            synchronized (this) {
7714                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7715            }
7716        } finally {
7717            Binder.restoreCallingIdentity(ident);
7718        }
7719        if (task != null) {
7720            startLockTaskMode(task);
7721        }
7722    }
7723
7724    @Override
7725    public void startLockTaskMode(IBinder token) {
7726        final TaskRecord task;
7727        long ident = Binder.clearCallingIdentity();
7728        try {
7729            synchronized (this) {
7730                final ActivityRecord r = ActivityRecord.forToken(token);
7731                if (r == null) {
7732                    return;
7733                }
7734                task = r.task;
7735            }
7736        } finally {
7737            Binder.restoreCallingIdentity(ident);
7738        }
7739        if (task != null) {
7740            startLockTaskMode(task);
7741        }
7742    }
7743
7744    @Override
7745    public void startLockTaskModeOnCurrent() throws RemoteException {
7746        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7747        ActivityRecord r = null;
7748        synchronized (this) {
7749            r = mStackSupervisor.topRunningActivityLocked();
7750        }
7751        startLockTaskMode(r.task);
7752    }
7753
7754    @Override
7755    public void stopLockTaskMode() {
7756        // Verify that the user matches the package of the intent for the TaskRecord
7757        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7758        // and stopLockTaskMode.
7759        final int callingUid = Binder.getCallingUid();
7760        if (callingUid != Process.SYSTEM_UID) {
7761            try {
7762                String pkg =
7763                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7764                int uid = mContext.getPackageManager().getPackageUid(pkg,
7765                        Binder.getCallingUserHandle().getIdentifier());
7766                if (uid != callingUid) {
7767                    throw new SecurityException("Invalid uid, expected " + uid);
7768                }
7769            } catch (NameNotFoundException e) {
7770                Log.d(TAG, "stopLockTaskMode " + e);
7771                return;
7772            }
7773        }
7774        long ident = Binder.clearCallingIdentity();
7775        try {
7776            Log.d(TAG, "stopLockTaskMode");
7777            // Stop lock task
7778            synchronized (this) {
7779                mStackSupervisor.setLockTaskModeLocked(null, false);
7780            }
7781        } finally {
7782            Binder.restoreCallingIdentity(ident);
7783        }
7784    }
7785
7786    @Override
7787    public void stopLockTaskModeOnCurrent() throws RemoteException {
7788        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7789        long ident = Binder.clearCallingIdentity();
7790        try {
7791            stopLockTaskMode();
7792        } finally {
7793            Binder.restoreCallingIdentity(ident);
7794        }
7795    }
7796
7797    @Override
7798    public boolean isInLockTaskMode() {
7799        synchronized (this) {
7800            return mStackSupervisor.isInLockTaskMode();
7801        }
7802    }
7803
7804    // =========================================================
7805    // CONTENT PROVIDERS
7806    // =========================================================
7807
7808    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7809        List<ProviderInfo> providers = null;
7810        try {
7811            providers = AppGlobals.getPackageManager().
7812                queryContentProviders(app.processName, app.uid,
7813                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7814        } catch (RemoteException ex) {
7815        }
7816        if (DEBUG_MU)
7817            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7818        int userId = app.userId;
7819        if (providers != null) {
7820            int N = providers.size();
7821            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7822            for (int i=0; i<N; i++) {
7823                ProviderInfo cpi =
7824                    (ProviderInfo)providers.get(i);
7825                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7826                        cpi.name, cpi.flags);
7827                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7828                    // This is a singleton provider, but a user besides the
7829                    // default user is asking to initialize a process it runs
7830                    // in...  well, no, it doesn't actually run in this process,
7831                    // it runs in the process of the default user.  Get rid of it.
7832                    providers.remove(i);
7833                    N--;
7834                    i--;
7835                    continue;
7836                }
7837
7838                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7839                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7840                if (cpr == null) {
7841                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7842                    mProviderMap.putProviderByClass(comp, cpr);
7843                }
7844                if (DEBUG_MU)
7845                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7846                app.pubProviders.put(cpi.name, cpr);
7847                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7848                    // Don't add this if it is a platform component that is marked
7849                    // to run in multiple processes, because this is actually
7850                    // part of the framework so doesn't make sense to track as a
7851                    // separate apk in the process.
7852                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7853                }
7854                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7855            }
7856        }
7857        return providers;
7858    }
7859
7860    /**
7861     * Check if {@link ProcessRecord} has a possible chance at accessing the
7862     * given {@link ProviderInfo}. Final permission checking is always done
7863     * in {@link ContentProvider}.
7864     */
7865    private final String checkContentProviderPermissionLocked(
7866            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7867        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7868        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7869        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7870        // Looking for cross-user grants before to enforce the typical cross-users permissions
7871        if (userId != UserHandle.getUserId(callingUid)) {
7872            if (perms != null) {
7873                for (GrantUri grantUri : perms.keySet()) {
7874                    if (grantUri.sourceUserId == userId) {
7875                        String authority = grantUri.uri.getAuthority();
7876                        if (authority.equals(cpi.authority)) {
7877                            return null;
7878                        }
7879                    }
7880                }
7881            }
7882        }
7883        if (checkUser) {
7884            userId = handleIncomingUser(callingPid, callingUid, userId,
7885                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7886        }
7887        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7888                cpi.applicationInfo.uid, cpi.exported)
7889                == PackageManager.PERMISSION_GRANTED) {
7890            return null;
7891        }
7892        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7893                cpi.applicationInfo.uid, cpi.exported)
7894                == PackageManager.PERMISSION_GRANTED) {
7895            return null;
7896        }
7897
7898        PathPermission[] pps = cpi.pathPermissions;
7899        if (pps != null) {
7900            int i = pps.length;
7901            while (i > 0) {
7902                i--;
7903                PathPermission pp = pps[i];
7904                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7905                        cpi.applicationInfo.uid, cpi.exported)
7906                        == PackageManager.PERMISSION_GRANTED) {
7907                    return null;
7908                }
7909                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7910                        cpi.applicationInfo.uid, cpi.exported)
7911                        == PackageManager.PERMISSION_GRANTED) {
7912                    return null;
7913                }
7914            }
7915        }
7916
7917        if (perms != null) {
7918            for (GrantUri grantUri : perms.keySet()) {
7919                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7920                    return null;
7921                }
7922            }
7923        }
7924
7925        String msg;
7926        if (!cpi.exported) {
7927            msg = "Permission Denial: opening provider " + cpi.name
7928                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7929                    + ", uid=" + callingUid + ") that is not exported from uid "
7930                    + cpi.applicationInfo.uid;
7931        } else {
7932            msg = "Permission Denial: opening provider " + cpi.name
7933                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7934                    + ", uid=" + callingUid + ") requires "
7935                    + cpi.readPermission + " or " + cpi.writePermission;
7936        }
7937        Slog.w(TAG, msg);
7938        return msg;
7939    }
7940
7941    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7942            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7943        if (r != null) {
7944            for (int i=0; i<r.conProviders.size(); i++) {
7945                ContentProviderConnection conn = r.conProviders.get(i);
7946                if (conn.provider == cpr) {
7947                    if (DEBUG_PROVIDER) Slog.v(TAG,
7948                            "Adding provider requested by "
7949                            + r.processName + " from process "
7950                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7951                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7952                    if (stable) {
7953                        conn.stableCount++;
7954                        conn.numStableIncs++;
7955                    } else {
7956                        conn.unstableCount++;
7957                        conn.numUnstableIncs++;
7958                    }
7959                    return conn;
7960                }
7961            }
7962            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7963            if (stable) {
7964                conn.stableCount = 1;
7965                conn.numStableIncs = 1;
7966            } else {
7967                conn.unstableCount = 1;
7968                conn.numUnstableIncs = 1;
7969            }
7970            cpr.connections.add(conn);
7971            r.conProviders.add(conn);
7972            return conn;
7973        }
7974        cpr.addExternalProcessHandleLocked(externalProcessToken);
7975        return null;
7976    }
7977
7978    boolean decProviderCountLocked(ContentProviderConnection conn,
7979            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7980        if (conn != null) {
7981            cpr = conn.provider;
7982            if (DEBUG_PROVIDER) Slog.v(TAG,
7983                    "Removing provider requested by "
7984                    + conn.client.processName + " from process "
7985                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7986                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7987            if (stable) {
7988                conn.stableCount--;
7989            } else {
7990                conn.unstableCount--;
7991            }
7992            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7993                cpr.connections.remove(conn);
7994                conn.client.conProviders.remove(conn);
7995                return true;
7996            }
7997            return false;
7998        }
7999        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8000        return false;
8001    }
8002
8003    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8004            String name, IBinder token, boolean stable, int userId) {
8005        ContentProviderRecord cpr;
8006        ContentProviderConnection conn = null;
8007        ProviderInfo cpi = null;
8008
8009        synchronized(this) {
8010            ProcessRecord r = null;
8011            if (caller != null) {
8012                r = getRecordForAppLocked(caller);
8013                if (r == null) {
8014                    throw new SecurityException(
8015                            "Unable to find app for caller " + caller
8016                          + " (pid=" + Binder.getCallingPid()
8017                          + ") when getting content provider " + name);
8018                }
8019            }
8020
8021            boolean checkCrossUser = true;
8022
8023            // First check if this content provider has been published...
8024            cpr = mProviderMap.getProviderByName(name, userId);
8025            // If that didn't work, check if it exists for user 0 and then
8026            // verify that it's a singleton provider before using it.
8027            if (cpr == null && userId != UserHandle.USER_OWNER) {
8028                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8029                if (cpr != null) {
8030                    cpi = cpr.info;
8031                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8032                            cpi.name, cpi.flags)
8033                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8034                        userId = UserHandle.USER_OWNER;
8035                        checkCrossUser = false;
8036                    } else {
8037                        cpr = null;
8038                        cpi = null;
8039                    }
8040                }
8041            }
8042
8043            boolean providerRunning = cpr != null;
8044            if (providerRunning) {
8045                cpi = cpr.info;
8046                String msg;
8047                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8048                        != null) {
8049                    throw new SecurityException(msg);
8050                }
8051
8052                if (r != null && cpr.canRunHere(r)) {
8053                    // This provider has been published or is in the process
8054                    // of being published...  but it is also allowed to run
8055                    // in the caller's process, so don't make a connection
8056                    // and just let the caller instantiate its own instance.
8057                    ContentProviderHolder holder = cpr.newHolder(null);
8058                    // don't give caller the provider object, it needs
8059                    // to make its own.
8060                    holder.provider = null;
8061                    return holder;
8062                }
8063
8064                final long origId = Binder.clearCallingIdentity();
8065
8066                // In this case the provider instance already exists, so we can
8067                // return it right away.
8068                conn = incProviderCountLocked(r, cpr, token, stable);
8069                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8070                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8071                        // If this is a perceptible app accessing the provider,
8072                        // make sure to count it as being accessed and thus
8073                        // back up on the LRU list.  This is good because
8074                        // content providers are often expensive to start.
8075                        updateLruProcessLocked(cpr.proc, false, null);
8076                    }
8077                }
8078
8079                if (cpr.proc != null) {
8080                    if (false) {
8081                        if (cpr.name.flattenToShortString().equals(
8082                                "com.android.providers.calendar/.CalendarProvider2")) {
8083                            Slog.v(TAG, "****************** KILLING "
8084                                + cpr.name.flattenToShortString());
8085                            Process.killProcess(cpr.proc.pid);
8086                        }
8087                    }
8088                    boolean success = updateOomAdjLocked(cpr.proc);
8089                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8090                    // NOTE: there is still a race here where a signal could be
8091                    // pending on the process even though we managed to update its
8092                    // adj level.  Not sure what to do about this, but at least
8093                    // the race is now smaller.
8094                    if (!success) {
8095                        // Uh oh...  it looks like the provider's process
8096                        // has been killed on us.  We need to wait for a new
8097                        // process to be started, and make sure its death
8098                        // doesn't kill our process.
8099                        Slog.i(TAG,
8100                                "Existing provider " + cpr.name.flattenToShortString()
8101                                + " is crashing; detaching " + r);
8102                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8103                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8104                        if (!lastRef) {
8105                            // This wasn't the last ref our process had on
8106                            // the provider...  we have now been killed, bail.
8107                            return null;
8108                        }
8109                        providerRunning = false;
8110                        conn = null;
8111                    }
8112                }
8113
8114                Binder.restoreCallingIdentity(origId);
8115            }
8116
8117            boolean singleton;
8118            if (!providerRunning) {
8119                try {
8120                    cpi = AppGlobals.getPackageManager().
8121                        resolveContentProvider(name,
8122                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8123                } catch (RemoteException ex) {
8124                }
8125                if (cpi == null) {
8126                    return null;
8127                }
8128                // If the provider is a singleton AND
8129                // (it's a call within the same user || the provider is a
8130                // privileged app)
8131                // Then allow connecting to the singleton provider
8132                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8133                        cpi.name, cpi.flags)
8134                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8135                if (singleton) {
8136                    userId = UserHandle.USER_OWNER;
8137                }
8138                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8139
8140                String msg;
8141                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8142                        != null) {
8143                    throw new SecurityException(msg);
8144                }
8145
8146                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8147                        && !cpi.processName.equals("system")) {
8148                    // If this content provider does not run in the system
8149                    // process, and the system is not yet ready to run other
8150                    // processes, then fail fast instead of hanging.
8151                    throw new IllegalArgumentException(
8152                            "Attempt to launch content provider before system ready");
8153                }
8154
8155                // Make sure that the user who owns this provider is started.  If not,
8156                // we don't want to allow it to run.
8157                if (mStartedUsers.get(userId) == null) {
8158                    Slog.w(TAG, "Unable to launch app "
8159                            + cpi.applicationInfo.packageName + "/"
8160                            + cpi.applicationInfo.uid + " for provider "
8161                            + name + ": user " + userId + " is stopped");
8162                    return null;
8163                }
8164
8165                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8166                cpr = mProviderMap.getProviderByClass(comp, userId);
8167                final boolean firstClass = cpr == null;
8168                if (firstClass) {
8169                    try {
8170                        ApplicationInfo ai =
8171                            AppGlobals.getPackageManager().
8172                                getApplicationInfo(
8173                                        cpi.applicationInfo.packageName,
8174                                        STOCK_PM_FLAGS, userId);
8175                        if (ai == null) {
8176                            Slog.w(TAG, "No package info for content provider "
8177                                    + cpi.name);
8178                            return null;
8179                        }
8180                        ai = getAppInfoForUser(ai, userId);
8181                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8182                    } catch (RemoteException ex) {
8183                        // pm is in same process, this will never happen.
8184                    }
8185                }
8186
8187                if (r != null && cpr.canRunHere(r)) {
8188                    // If this is a multiprocess provider, then just return its
8189                    // info and allow the caller to instantiate it.  Only do
8190                    // this if the provider is the same user as the caller's
8191                    // process, or can run as root (so can be in any process).
8192                    return cpr.newHolder(null);
8193                }
8194
8195                if (DEBUG_PROVIDER) {
8196                    RuntimeException e = new RuntimeException("here");
8197                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8198                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8199                }
8200
8201                // This is single process, and our app is now connecting to it.
8202                // See if we are already in the process of launching this
8203                // provider.
8204                final int N = mLaunchingProviders.size();
8205                int i;
8206                for (i=0; i<N; i++) {
8207                    if (mLaunchingProviders.get(i) == cpr) {
8208                        break;
8209                    }
8210                }
8211
8212                // If the provider is not already being launched, then get it
8213                // started.
8214                if (i >= N) {
8215                    final long origId = Binder.clearCallingIdentity();
8216
8217                    try {
8218                        // Content provider is now in use, its package can't be stopped.
8219                        try {
8220                            AppGlobals.getPackageManager().setPackageStoppedState(
8221                                    cpr.appInfo.packageName, false, userId);
8222                        } catch (RemoteException e) {
8223                        } catch (IllegalArgumentException e) {
8224                            Slog.w(TAG, "Failed trying to unstop package "
8225                                    + cpr.appInfo.packageName + ": " + e);
8226                        }
8227
8228                        // Use existing process if already started
8229                        ProcessRecord proc = getProcessRecordLocked(
8230                                cpi.processName, cpr.appInfo.uid, false);
8231                        if (proc != null && proc.thread != null) {
8232                            if (DEBUG_PROVIDER) {
8233                                Slog.d(TAG, "Installing in existing process " + proc);
8234                            }
8235                            proc.pubProviders.put(cpi.name, cpr);
8236                            try {
8237                                proc.thread.scheduleInstallProvider(cpi);
8238                            } catch (RemoteException e) {
8239                            }
8240                        } else {
8241                            proc = startProcessLocked(cpi.processName,
8242                                    cpr.appInfo, false, 0, "content provider",
8243                                    new ComponentName(cpi.applicationInfo.packageName,
8244                                            cpi.name), false, false, false);
8245                            if (proc == null) {
8246                                Slog.w(TAG, "Unable to launch app "
8247                                        + cpi.applicationInfo.packageName + "/"
8248                                        + cpi.applicationInfo.uid + " for provider "
8249                                        + name + ": process is bad");
8250                                return null;
8251                            }
8252                        }
8253                        cpr.launchingApp = proc;
8254                        mLaunchingProviders.add(cpr);
8255                    } finally {
8256                        Binder.restoreCallingIdentity(origId);
8257                    }
8258                }
8259
8260                // Make sure the provider is published (the same provider class
8261                // may be published under multiple names).
8262                if (firstClass) {
8263                    mProviderMap.putProviderByClass(comp, cpr);
8264                }
8265
8266                mProviderMap.putProviderByName(name, cpr);
8267                conn = incProviderCountLocked(r, cpr, token, stable);
8268                if (conn != null) {
8269                    conn.waiting = true;
8270                }
8271            }
8272        }
8273
8274        // Wait for the provider to be published...
8275        synchronized (cpr) {
8276            while (cpr.provider == null) {
8277                if (cpr.launchingApp == null) {
8278                    Slog.w(TAG, "Unable to launch app "
8279                            + cpi.applicationInfo.packageName + "/"
8280                            + cpi.applicationInfo.uid + " for provider "
8281                            + name + ": launching app became null");
8282                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8283                            UserHandle.getUserId(cpi.applicationInfo.uid),
8284                            cpi.applicationInfo.packageName,
8285                            cpi.applicationInfo.uid, name);
8286                    return null;
8287                }
8288                try {
8289                    if (DEBUG_MU) {
8290                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8291                                + cpr.launchingApp);
8292                    }
8293                    if (conn != null) {
8294                        conn.waiting = true;
8295                    }
8296                    cpr.wait();
8297                } catch (InterruptedException ex) {
8298                } finally {
8299                    if (conn != null) {
8300                        conn.waiting = false;
8301                    }
8302                }
8303            }
8304        }
8305        return cpr != null ? cpr.newHolder(conn) : null;
8306    }
8307
8308    @Override
8309    public final ContentProviderHolder getContentProvider(
8310            IApplicationThread caller, String name, int userId, boolean stable) {
8311        enforceNotIsolatedCaller("getContentProvider");
8312        if (caller == null) {
8313            String msg = "null IApplicationThread when getting content provider "
8314                    + name;
8315            Slog.w(TAG, msg);
8316            throw new SecurityException(msg);
8317        }
8318        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8319        // with cross-user grant.
8320        return getContentProviderImpl(caller, name, null, stable, userId);
8321    }
8322
8323    public ContentProviderHolder getContentProviderExternal(
8324            String name, int userId, IBinder token) {
8325        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8326            "Do not have permission in call getContentProviderExternal()");
8327        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8328                false, true, "getContentProvider", null);
8329        return getContentProviderExternalUnchecked(name, token, userId);
8330    }
8331
8332    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8333            IBinder token, int userId) {
8334        return getContentProviderImpl(null, name, token, true, userId);
8335    }
8336
8337    /**
8338     * Drop a content provider from a ProcessRecord's bookkeeping
8339     */
8340    public void removeContentProvider(IBinder connection, boolean stable) {
8341        enforceNotIsolatedCaller("removeContentProvider");
8342        long ident = Binder.clearCallingIdentity();
8343        try {
8344            synchronized (this) {
8345                ContentProviderConnection conn;
8346                try {
8347                    conn = (ContentProviderConnection)connection;
8348                } catch (ClassCastException e) {
8349                    String msg ="removeContentProvider: " + connection
8350                            + " not a ContentProviderConnection";
8351                    Slog.w(TAG, msg);
8352                    throw new IllegalArgumentException(msg);
8353                }
8354                if (conn == null) {
8355                    throw new NullPointerException("connection is null");
8356                }
8357                if (decProviderCountLocked(conn, null, null, stable)) {
8358                    updateOomAdjLocked();
8359                }
8360            }
8361        } finally {
8362            Binder.restoreCallingIdentity(ident);
8363        }
8364    }
8365
8366    public void removeContentProviderExternal(String name, IBinder token) {
8367        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8368            "Do not have permission in call removeContentProviderExternal()");
8369        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8370    }
8371
8372    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8373        synchronized (this) {
8374            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8375            if(cpr == null) {
8376                //remove from mProvidersByClass
8377                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8378                return;
8379            }
8380
8381            //update content provider record entry info
8382            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8383            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8384            if (localCpr.hasExternalProcessHandles()) {
8385                if (localCpr.removeExternalProcessHandleLocked(token)) {
8386                    updateOomAdjLocked();
8387                } else {
8388                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8389                            + " with no external reference for token: "
8390                            + token + ".");
8391                }
8392            } else {
8393                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8394                        + " with no external references.");
8395            }
8396        }
8397    }
8398
8399    public final void publishContentProviders(IApplicationThread caller,
8400            List<ContentProviderHolder> providers) {
8401        if (providers == null) {
8402            return;
8403        }
8404
8405        enforceNotIsolatedCaller("publishContentProviders");
8406        synchronized (this) {
8407            final ProcessRecord r = getRecordForAppLocked(caller);
8408            if (DEBUG_MU)
8409                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8410            if (r == null) {
8411                throw new SecurityException(
8412                        "Unable to find app for caller " + caller
8413                      + " (pid=" + Binder.getCallingPid()
8414                      + ") when publishing content providers");
8415            }
8416
8417            final long origId = Binder.clearCallingIdentity();
8418
8419            final int N = providers.size();
8420            for (int i=0; i<N; i++) {
8421                ContentProviderHolder src = providers.get(i);
8422                if (src == null || src.info == null || src.provider == null) {
8423                    continue;
8424                }
8425                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8426                if (DEBUG_MU)
8427                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8428                if (dst != null) {
8429                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8430                    mProviderMap.putProviderByClass(comp, dst);
8431                    String names[] = dst.info.authority.split(";");
8432                    for (int j = 0; j < names.length; j++) {
8433                        mProviderMap.putProviderByName(names[j], dst);
8434                    }
8435
8436                    int NL = mLaunchingProviders.size();
8437                    int j;
8438                    for (j=0; j<NL; j++) {
8439                        if (mLaunchingProviders.get(j) == dst) {
8440                            mLaunchingProviders.remove(j);
8441                            j--;
8442                            NL--;
8443                        }
8444                    }
8445                    synchronized (dst) {
8446                        dst.provider = src.provider;
8447                        dst.proc = r;
8448                        dst.notifyAll();
8449                    }
8450                    updateOomAdjLocked(r);
8451                }
8452            }
8453
8454            Binder.restoreCallingIdentity(origId);
8455        }
8456    }
8457
8458    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8459        ContentProviderConnection conn;
8460        try {
8461            conn = (ContentProviderConnection)connection;
8462        } catch (ClassCastException e) {
8463            String msg ="refContentProvider: " + connection
8464                    + " not a ContentProviderConnection";
8465            Slog.w(TAG, msg);
8466            throw new IllegalArgumentException(msg);
8467        }
8468        if (conn == null) {
8469            throw new NullPointerException("connection is null");
8470        }
8471
8472        synchronized (this) {
8473            if (stable > 0) {
8474                conn.numStableIncs += stable;
8475            }
8476            stable = conn.stableCount + stable;
8477            if (stable < 0) {
8478                throw new IllegalStateException("stableCount < 0: " + stable);
8479            }
8480
8481            if (unstable > 0) {
8482                conn.numUnstableIncs += unstable;
8483            }
8484            unstable = conn.unstableCount + unstable;
8485            if (unstable < 0) {
8486                throw new IllegalStateException("unstableCount < 0: " + unstable);
8487            }
8488
8489            if ((stable+unstable) <= 0) {
8490                throw new IllegalStateException("ref counts can't go to zero here: stable="
8491                        + stable + " unstable=" + unstable);
8492            }
8493            conn.stableCount = stable;
8494            conn.unstableCount = unstable;
8495            return !conn.dead;
8496        }
8497    }
8498
8499    public void unstableProviderDied(IBinder connection) {
8500        ContentProviderConnection conn;
8501        try {
8502            conn = (ContentProviderConnection)connection;
8503        } catch (ClassCastException e) {
8504            String msg ="refContentProvider: " + connection
8505                    + " not a ContentProviderConnection";
8506            Slog.w(TAG, msg);
8507            throw new IllegalArgumentException(msg);
8508        }
8509        if (conn == null) {
8510            throw new NullPointerException("connection is null");
8511        }
8512
8513        // Safely retrieve the content provider associated with the connection.
8514        IContentProvider provider;
8515        synchronized (this) {
8516            provider = conn.provider.provider;
8517        }
8518
8519        if (provider == null) {
8520            // Um, yeah, we're way ahead of you.
8521            return;
8522        }
8523
8524        // Make sure the caller is being honest with us.
8525        if (provider.asBinder().pingBinder()) {
8526            // Er, no, still looks good to us.
8527            synchronized (this) {
8528                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8529                        + " says " + conn + " died, but we don't agree");
8530                return;
8531            }
8532        }
8533
8534        // Well look at that!  It's dead!
8535        synchronized (this) {
8536            if (conn.provider.provider != provider) {
8537                // But something changed...  good enough.
8538                return;
8539            }
8540
8541            ProcessRecord proc = conn.provider.proc;
8542            if (proc == null || proc.thread == null) {
8543                // Seems like the process is already cleaned up.
8544                return;
8545            }
8546
8547            // As far as we're concerned, this is just like receiving a
8548            // death notification...  just a bit prematurely.
8549            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8550                    + ") early provider death");
8551            final long ident = Binder.clearCallingIdentity();
8552            try {
8553                appDiedLocked(proc, proc.pid, proc.thread);
8554            } finally {
8555                Binder.restoreCallingIdentity(ident);
8556            }
8557        }
8558    }
8559
8560    @Override
8561    public void appNotRespondingViaProvider(IBinder connection) {
8562        enforceCallingPermission(
8563                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8564
8565        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8566        if (conn == null) {
8567            Slog.w(TAG, "ContentProviderConnection is null");
8568            return;
8569        }
8570
8571        final ProcessRecord host = conn.provider.proc;
8572        if (host == null) {
8573            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8574            return;
8575        }
8576
8577        final long token = Binder.clearCallingIdentity();
8578        try {
8579            appNotResponding(host, null, null, false, "ContentProvider not responding");
8580        } finally {
8581            Binder.restoreCallingIdentity(token);
8582        }
8583    }
8584
8585    public final void installSystemProviders() {
8586        List<ProviderInfo> providers;
8587        synchronized (this) {
8588            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8589            providers = generateApplicationProvidersLocked(app);
8590            if (providers != null) {
8591                for (int i=providers.size()-1; i>=0; i--) {
8592                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8593                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8594                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8595                                + ": not system .apk");
8596                        providers.remove(i);
8597                    }
8598                }
8599            }
8600        }
8601        if (providers != null) {
8602            mSystemThread.installSystemProviders(providers);
8603        }
8604
8605        mCoreSettingsObserver = new CoreSettingsObserver(this);
8606
8607        mUsageStatsService.monitorPackages();
8608    }
8609
8610    /**
8611     * Allows app to retrieve the MIME type of a URI without having permission
8612     * to access its content provider.
8613     *
8614     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8615     *
8616     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8617     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8618     */
8619    public String getProviderMimeType(Uri uri, int userId) {
8620        enforceNotIsolatedCaller("getProviderMimeType");
8621        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8622                userId, false, true, "getProviderMimeType", null);
8623        final String name = uri.getAuthority();
8624        final long ident = Binder.clearCallingIdentity();
8625        ContentProviderHolder holder = null;
8626
8627        try {
8628            holder = getContentProviderExternalUnchecked(name, null, userId);
8629            if (holder != null) {
8630                return holder.provider.getType(uri);
8631            }
8632        } catch (RemoteException e) {
8633            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8634            return null;
8635        } finally {
8636            if (holder != null) {
8637                removeContentProviderExternalUnchecked(name, null, userId);
8638            }
8639            Binder.restoreCallingIdentity(ident);
8640        }
8641
8642        return null;
8643    }
8644
8645    // =========================================================
8646    // GLOBAL MANAGEMENT
8647    // =========================================================
8648
8649    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8650            boolean isolated) {
8651        String proc = customProcess != null ? customProcess : info.processName;
8652        BatteryStatsImpl.Uid.Proc ps = null;
8653        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8654        int uid = info.uid;
8655        if (isolated) {
8656            int userId = UserHandle.getUserId(uid);
8657            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8658            while (true) {
8659                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8660                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8661                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8662                }
8663                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8664                mNextIsolatedProcessUid++;
8665                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8666                    // No process for this uid, use it.
8667                    break;
8668                }
8669                stepsLeft--;
8670                if (stepsLeft <= 0) {
8671                    return null;
8672                }
8673            }
8674        }
8675        return new ProcessRecord(stats, info, proc, uid);
8676    }
8677
8678    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8679            String abiOverride) {
8680        ProcessRecord app;
8681        if (!isolated) {
8682            app = getProcessRecordLocked(info.processName, info.uid, true);
8683        } else {
8684            app = null;
8685        }
8686
8687        if (app == null) {
8688            app = newProcessRecordLocked(info, null, isolated);
8689            mProcessNames.put(info.processName, app.uid, app);
8690            if (isolated) {
8691                mIsolatedProcesses.put(app.uid, app);
8692            }
8693            updateLruProcessLocked(app, false, null);
8694            updateOomAdjLocked();
8695        }
8696
8697        // This package really, really can not be stopped.
8698        try {
8699            AppGlobals.getPackageManager().setPackageStoppedState(
8700                    info.packageName, false, UserHandle.getUserId(app.uid));
8701        } catch (RemoteException e) {
8702        } catch (IllegalArgumentException e) {
8703            Slog.w(TAG, "Failed trying to unstop package "
8704                    + info.packageName + ": " + e);
8705        }
8706
8707        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8708                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8709            app.persistent = true;
8710            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8711        }
8712        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8713            mPersistentStartingProcesses.add(app);
8714            startProcessLocked(app, "added application", app.processName,
8715                    abiOverride);
8716        }
8717
8718        return app;
8719    }
8720
8721    public void unhandledBack() {
8722        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8723                "unhandledBack()");
8724
8725        synchronized(this) {
8726            final long origId = Binder.clearCallingIdentity();
8727            try {
8728                getFocusedStack().unhandledBackLocked();
8729            } finally {
8730                Binder.restoreCallingIdentity(origId);
8731            }
8732        }
8733    }
8734
8735    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8736        enforceNotIsolatedCaller("openContentUri");
8737        final int userId = UserHandle.getCallingUserId();
8738        String name = uri.getAuthority();
8739        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8740        ParcelFileDescriptor pfd = null;
8741        if (cph != null) {
8742            // We record the binder invoker's uid in thread-local storage before
8743            // going to the content provider to open the file.  Later, in the code
8744            // that handles all permissions checks, we look for this uid and use
8745            // that rather than the Activity Manager's own uid.  The effect is that
8746            // we do the check against the caller's permissions even though it looks
8747            // to the content provider like the Activity Manager itself is making
8748            // the request.
8749            sCallerIdentity.set(new Identity(
8750                    Binder.getCallingPid(), Binder.getCallingUid()));
8751            try {
8752                pfd = cph.provider.openFile(null, uri, "r", null);
8753            } catch (FileNotFoundException e) {
8754                // do nothing; pfd will be returned null
8755            } finally {
8756                // Ensure that whatever happens, we clean up the identity state
8757                sCallerIdentity.remove();
8758            }
8759
8760            // We've got the fd now, so we're done with the provider.
8761            removeContentProviderExternalUnchecked(name, null, userId);
8762        } else {
8763            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8764        }
8765        return pfd;
8766    }
8767
8768    // Actually is sleeping or shutting down or whatever else in the future
8769    // is an inactive state.
8770    public boolean isSleepingOrShuttingDown() {
8771        return mSleeping || mShuttingDown;
8772    }
8773
8774    public boolean isSleeping() {
8775        return mSleeping;
8776    }
8777
8778    void goingToSleep() {
8779        synchronized(this) {
8780            mWentToSleep = true;
8781            updateEventDispatchingLocked();
8782            goToSleepIfNeededLocked();
8783        }
8784    }
8785
8786    void finishRunningVoiceLocked() {
8787        if (mRunningVoice) {
8788            mRunningVoice = false;
8789            goToSleepIfNeededLocked();
8790        }
8791    }
8792
8793    void goToSleepIfNeededLocked() {
8794        if (mWentToSleep && !mRunningVoice) {
8795            if (!mSleeping) {
8796                mSleeping = true;
8797                mStackSupervisor.goingToSleepLocked();
8798
8799                // Initialize the wake times of all processes.
8800                checkExcessivePowerUsageLocked(false);
8801                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8802                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8803                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8804            }
8805        }
8806    }
8807
8808    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8809        mTaskPersister.notify(task, flush);
8810    }
8811
8812    @Override
8813    public boolean shutdown(int timeout) {
8814        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8815                != PackageManager.PERMISSION_GRANTED) {
8816            throw new SecurityException("Requires permission "
8817                    + android.Manifest.permission.SHUTDOWN);
8818        }
8819
8820        boolean timedout = false;
8821
8822        synchronized(this) {
8823            mShuttingDown = true;
8824            updateEventDispatchingLocked();
8825            timedout = mStackSupervisor.shutdownLocked(timeout);
8826        }
8827
8828        mAppOpsService.shutdown();
8829        mUsageStatsService.shutdown();
8830        mBatteryStatsService.shutdown();
8831        synchronized (this) {
8832            mProcessStats.shutdownLocked();
8833        }
8834        notifyTaskPersisterLocked(null, true);
8835
8836        return timedout;
8837    }
8838
8839    public final void activitySlept(IBinder token) {
8840        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8841
8842        final long origId = Binder.clearCallingIdentity();
8843
8844        synchronized (this) {
8845            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8846            if (r != null) {
8847                mStackSupervisor.activitySleptLocked(r);
8848            }
8849        }
8850
8851        Binder.restoreCallingIdentity(origId);
8852    }
8853
8854    void logLockScreen(String msg) {
8855        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8856                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8857                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8858                mStackSupervisor.mDismissKeyguardOnNextActivity);
8859    }
8860
8861    private void comeOutOfSleepIfNeededLocked() {
8862        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8863            if (mSleeping) {
8864                mSleeping = false;
8865                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8866            }
8867        }
8868    }
8869
8870    void wakingUp() {
8871        synchronized(this) {
8872            mWentToSleep = false;
8873            updateEventDispatchingLocked();
8874            comeOutOfSleepIfNeededLocked();
8875        }
8876    }
8877
8878    void startRunningVoiceLocked() {
8879        if (!mRunningVoice) {
8880            mRunningVoice = true;
8881            comeOutOfSleepIfNeededLocked();
8882        }
8883    }
8884
8885    private void updateEventDispatchingLocked() {
8886        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8887    }
8888
8889    public void setLockScreenShown(boolean shown) {
8890        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8891                != PackageManager.PERMISSION_GRANTED) {
8892            throw new SecurityException("Requires permission "
8893                    + android.Manifest.permission.DEVICE_POWER);
8894        }
8895
8896        synchronized(this) {
8897            long ident = Binder.clearCallingIdentity();
8898            try {
8899                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8900                mLockScreenShown = shown;
8901                comeOutOfSleepIfNeededLocked();
8902            } finally {
8903                Binder.restoreCallingIdentity(ident);
8904            }
8905        }
8906    }
8907
8908    public void stopAppSwitches() {
8909        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8910                != PackageManager.PERMISSION_GRANTED) {
8911            throw new SecurityException("Requires permission "
8912                    + android.Manifest.permission.STOP_APP_SWITCHES);
8913        }
8914
8915        synchronized(this) {
8916            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8917                    + APP_SWITCH_DELAY_TIME;
8918            mDidAppSwitch = false;
8919            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8920            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8921            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8922        }
8923    }
8924
8925    public void resumeAppSwitches() {
8926        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8927                != PackageManager.PERMISSION_GRANTED) {
8928            throw new SecurityException("Requires permission "
8929                    + android.Manifest.permission.STOP_APP_SWITCHES);
8930        }
8931
8932        synchronized(this) {
8933            // Note that we don't execute any pending app switches... we will
8934            // let those wait until either the timeout, or the next start
8935            // activity request.
8936            mAppSwitchesAllowedTime = 0;
8937        }
8938    }
8939
8940    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8941            String name) {
8942        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8943            return true;
8944        }
8945
8946        final int perm = checkComponentPermission(
8947                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8948                callingUid, -1, true);
8949        if (perm == PackageManager.PERMISSION_GRANTED) {
8950            return true;
8951        }
8952
8953        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8954        return false;
8955    }
8956
8957    public void setDebugApp(String packageName, boolean waitForDebugger,
8958            boolean persistent) {
8959        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8960                "setDebugApp()");
8961
8962        long ident = Binder.clearCallingIdentity();
8963        try {
8964            // Note that this is not really thread safe if there are multiple
8965            // callers into it at the same time, but that's not a situation we
8966            // care about.
8967            if (persistent) {
8968                final ContentResolver resolver = mContext.getContentResolver();
8969                Settings.Global.putString(
8970                    resolver, Settings.Global.DEBUG_APP,
8971                    packageName);
8972                Settings.Global.putInt(
8973                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8974                    waitForDebugger ? 1 : 0);
8975            }
8976
8977            synchronized (this) {
8978                if (!persistent) {
8979                    mOrigDebugApp = mDebugApp;
8980                    mOrigWaitForDebugger = mWaitForDebugger;
8981                }
8982                mDebugApp = packageName;
8983                mWaitForDebugger = waitForDebugger;
8984                mDebugTransient = !persistent;
8985                if (packageName != null) {
8986                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8987                            false, UserHandle.USER_ALL, "set debug app");
8988                }
8989            }
8990        } finally {
8991            Binder.restoreCallingIdentity(ident);
8992        }
8993    }
8994
8995    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8996        synchronized (this) {
8997            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8998            if (!isDebuggable) {
8999                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9000                    throw new SecurityException("Process not debuggable: " + app.packageName);
9001                }
9002            }
9003
9004            mOpenGlTraceApp = processName;
9005        }
9006    }
9007
9008    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9009            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9010        synchronized (this) {
9011            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9012            if (!isDebuggable) {
9013                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9014                    throw new SecurityException("Process not debuggable: " + app.packageName);
9015                }
9016            }
9017            mProfileApp = processName;
9018            mProfileFile = profileFile;
9019            if (mProfileFd != null) {
9020                try {
9021                    mProfileFd.close();
9022                } catch (IOException e) {
9023                }
9024                mProfileFd = null;
9025            }
9026            mProfileFd = profileFd;
9027            mProfileType = 0;
9028            mAutoStopProfiler = autoStopProfiler;
9029        }
9030    }
9031
9032    @Override
9033    public void setAlwaysFinish(boolean enabled) {
9034        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9035                "setAlwaysFinish()");
9036
9037        Settings.Global.putInt(
9038                mContext.getContentResolver(),
9039                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9040
9041        synchronized (this) {
9042            mAlwaysFinishActivities = enabled;
9043        }
9044    }
9045
9046    @Override
9047    public void setActivityController(IActivityController controller) {
9048        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9049                "setActivityController()");
9050        synchronized (this) {
9051            mController = controller;
9052            Watchdog.getInstance().setActivityController(controller);
9053        }
9054    }
9055
9056    @Override
9057    public void setUserIsMonkey(boolean userIsMonkey) {
9058        synchronized (this) {
9059            synchronized (mPidsSelfLocked) {
9060                final int callingPid = Binder.getCallingPid();
9061                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9062                if (precessRecord == null) {
9063                    throw new SecurityException("Unknown process: " + callingPid);
9064                }
9065                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9066                    throw new SecurityException("Only an instrumentation process "
9067                            + "with a UiAutomation can call setUserIsMonkey");
9068                }
9069            }
9070            mUserIsMonkey = userIsMonkey;
9071        }
9072    }
9073
9074    @Override
9075    public boolean isUserAMonkey() {
9076        synchronized (this) {
9077            // If there is a controller also implies the user is a monkey.
9078            return (mUserIsMonkey || mController != null);
9079        }
9080    }
9081
9082    public void requestBugReport() {
9083        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9084        SystemProperties.set("ctl.start", "bugreport");
9085    }
9086
9087    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9088        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9089    }
9090
9091    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9092        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9093            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9094        }
9095        return KEY_DISPATCHING_TIMEOUT;
9096    }
9097
9098    @Override
9099    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9100        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9101                != PackageManager.PERMISSION_GRANTED) {
9102            throw new SecurityException("Requires permission "
9103                    + android.Manifest.permission.FILTER_EVENTS);
9104        }
9105        ProcessRecord proc;
9106        long timeout;
9107        synchronized (this) {
9108            synchronized (mPidsSelfLocked) {
9109                proc = mPidsSelfLocked.get(pid);
9110            }
9111            timeout = getInputDispatchingTimeoutLocked(proc);
9112        }
9113
9114        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9115            return -1;
9116        }
9117
9118        return timeout;
9119    }
9120
9121    /**
9122     * Handle input dispatching timeouts.
9123     * Returns whether input dispatching should be aborted or not.
9124     */
9125    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9126            final ActivityRecord activity, final ActivityRecord parent,
9127            final boolean aboveSystem, String reason) {
9128        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9129                != PackageManager.PERMISSION_GRANTED) {
9130            throw new SecurityException("Requires permission "
9131                    + android.Manifest.permission.FILTER_EVENTS);
9132        }
9133
9134        final String annotation;
9135        if (reason == null) {
9136            annotation = "Input dispatching timed out";
9137        } else {
9138            annotation = "Input dispatching timed out (" + reason + ")";
9139        }
9140
9141        if (proc != null) {
9142            synchronized (this) {
9143                if (proc.debugging) {
9144                    return false;
9145                }
9146
9147                if (mDidDexOpt) {
9148                    // Give more time since we were dexopting.
9149                    mDidDexOpt = false;
9150                    return false;
9151                }
9152
9153                if (proc.instrumentationClass != null) {
9154                    Bundle info = new Bundle();
9155                    info.putString("shortMsg", "keyDispatchingTimedOut");
9156                    info.putString("longMsg", annotation);
9157                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9158                    return true;
9159                }
9160            }
9161            mHandler.post(new Runnable() {
9162                @Override
9163                public void run() {
9164                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9165                }
9166            });
9167        }
9168
9169        return true;
9170    }
9171
9172    public Bundle getAssistContextExtras(int requestType) {
9173        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9174                "getAssistContextExtras()");
9175        PendingAssistExtras pae;
9176        Bundle extras = new Bundle();
9177        synchronized (this) {
9178            ActivityRecord activity = getFocusedStack().mResumedActivity;
9179            if (activity == null) {
9180                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9181                return null;
9182            }
9183            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9184            if (activity.app == null || activity.app.thread == null) {
9185                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9186                return extras;
9187            }
9188            if (activity.app.pid == Binder.getCallingPid()) {
9189                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9190                return extras;
9191            }
9192            pae = new PendingAssistExtras(activity);
9193            try {
9194                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9195                        requestType);
9196                mPendingAssistExtras.add(pae);
9197                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9198            } catch (RemoteException e) {
9199                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9200                return extras;
9201            }
9202        }
9203        synchronized (pae) {
9204            while (!pae.haveResult) {
9205                try {
9206                    pae.wait();
9207                } catch (InterruptedException e) {
9208                }
9209            }
9210            if (pae.result != null) {
9211                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9212            }
9213        }
9214        synchronized (this) {
9215            mPendingAssistExtras.remove(pae);
9216            mHandler.removeCallbacks(pae);
9217        }
9218        return extras;
9219    }
9220
9221    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9222        PendingAssistExtras pae = (PendingAssistExtras)token;
9223        synchronized (pae) {
9224            pae.result = extras;
9225            pae.haveResult = true;
9226            pae.notifyAll();
9227        }
9228    }
9229
9230    public void registerProcessObserver(IProcessObserver observer) {
9231        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9232                "registerProcessObserver()");
9233        synchronized (this) {
9234            mProcessObservers.register(observer);
9235        }
9236    }
9237
9238    @Override
9239    public void unregisterProcessObserver(IProcessObserver observer) {
9240        synchronized (this) {
9241            mProcessObservers.unregister(observer);
9242        }
9243    }
9244
9245    @Override
9246    public boolean convertFromTranslucent(IBinder token) {
9247        final long origId = Binder.clearCallingIdentity();
9248        try {
9249            synchronized (this) {
9250                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9251                if (r == null) {
9252                    return false;
9253                }
9254                if (r.changeWindowTranslucency(true)) {
9255                    mWindowManager.setAppFullscreen(token, true);
9256                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9257                    return true;
9258                }
9259                return false;
9260            }
9261        } finally {
9262            Binder.restoreCallingIdentity(origId);
9263        }
9264    }
9265
9266    @Override
9267    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9268        final long origId = Binder.clearCallingIdentity();
9269        try {
9270            synchronized (this) {
9271                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9272                if (r == null) {
9273                    return false;
9274                }
9275                if (r.changeWindowTranslucency(false)) {
9276                    r.task.stack.convertToTranslucent(r, options);
9277                    mWindowManager.setAppFullscreen(token, false);
9278                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9279                    return true;
9280                }
9281                return false;
9282            }
9283        } finally {
9284            Binder.restoreCallingIdentity(origId);
9285        }
9286    }
9287
9288    @Override
9289    public ActivityOptions getActivityOptions(IBinder token) {
9290        final long origId = Binder.clearCallingIdentity();
9291        try {
9292            synchronized (this) {
9293                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9294                if (r != null) {
9295                    final ActivityOptions activityOptions = r.pendingOptions;
9296                    r.pendingOptions = null;
9297                    return activityOptions;
9298                }
9299                return null;
9300            }
9301        } finally {
9302            Binder.restoreCallingIdentity(origId);
9303        }
9304    }
9305
9306    @Override
9307    public void setImmersive(IBinder token, boolean immersive) {
9308        synchronized(this) {
9309            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9310            if (r == null) {
9311                throw new IllegalArgumentException();
9312            }
9313            r.immersive = immersive;
9314
9315            // update associated state if we're frontmost
9316            if (r == mFocusedActivity) {
9317                if (DEBUG_IMMERSIVE) {
9318                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9319                }
9320                applyUpdateLockStateLocked(r);
9321            }
9322        }
9323    }
9324
9325    @Override
9326    public boolean isImmersive(IBinder token) {
9327        synchronized (this) {
9328            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9329            if (r == null) {
9330                throw new IllegalArgumentException();
9331            }
9332            return r.immersive;
9333        }
9334    }
9335
9336    public boolean isTopActivityImmersive() {
9337        enforceNotIsolatedCaller("startActivity");
9338        synchronized (this) {
9339            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9340            return (r != null) ? r.immersive : false;
9341        }
9342    }
9343
9344    public final void enterSafeMode() {
9345        synchronized(this) {
9346            // It only makes sense to do this before the system is ready
9347            // and started launching other packages.
9348            if (!mSystemReady) {
9349                try {
9350                    AppGlobals.getPackageManager().enterSafeMode();
9351                } catch (RemoteException e) {
9352                }
9353            }
9354
9355            mSafeMode = true;
9356        }
9357    }
9358
9359    public final void showSafeModeOverlay() {
9360        View v = LayoutInflater.from(mContext).inflate(
9361                com.android.internal.R.layout.safe_mode, null);
9362        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9363        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9364        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9365        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9366        lp.gravity = Gravity.BOTTOM | Gravity.START;
9367        lp.format = v.getBackground().getOpacity();
9368        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9369                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9370        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9371        ((WindowManager)mContext.getSystemService(
9372                Context.WINDOW_SERVICE)).addView(v, lp);
9373    }
9374
9375    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9376        if (!(sender instanceof PendingIntentRecord)) {
9377            return;
9378        }
9379        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9380        synchronized (stats) {
9381            if (mBatteryStatsService.isOnBattery()) {
9382                mBatteryStatsService.enforceCallingPermission();
9383                PendingIntentRecord rec = (PendingIntentRecord)sender;
9384                int MY_UID = Binder.getCallingUid();
9385                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9386                BatteryStatsImpl.Uid.Pkg pkg =
9387                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9388                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9389                pkg.incWakeupsLocked();
9390            }
9391        }
9392    }
9393
9394    public boolean killPids(int[] pids, String pReason, boolean secure) {
9395        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9396            throw new SecurityException("killPids only available to the system");
9397        }
9398        String reason = (pReason == null) ? "Unknown" : pReason;
9399        // XXX Note: don't acquire main activity lock here, because the window
9400        // manager calls in with its locks held.
9401
9402        boolean killed = false;
9403        synchronized (mPidsSelfLocked) {
9404            int[] types = new int[pids.length];
9405            int worstType = 0;
9406            for (int i=0; i<pids.length; i++) {
9407                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9408                if (proc != null) {
9409                    int type = proc.setAdj;
9410                    types[i] = type;
9411                    if (type > worstType) {
9412                        worstType = type;
9413                    }
9414                }
9415            }
9416
9417            // If the worst oom_adj is somewhere in the cached proc LRU range,
9418            // then constrain it so we will kill all cached procs.
9419            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9420                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9421                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9422            }
9423
9424            // If this is not a secure call, don't let it kill processes that
9425            // are important.
9426            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9427                worstType = ProcessList.SERVICE_ADJ;
9428            }
9429
9430            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9431            for (int i=0; i<pids.length; i++) {
9432                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9433                if (proc == null) {
9434                    continue;
9435                }
9436                int adj = proc.setAdj;
9437                if (adj >= worstType && !proc.killedByAm) {
9438                    killUnneededProcessLocked(proc, reason);
9439                    killed = true;
9440                }
9441            }
9442        }
9443        return killed;
9444    }
9445
9446    @Override
9447    public void killUid(int uid, String reason) {
9448        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9449            throw new SecurityException("killUid only available to the system");
9450        }
9451        synchronized (this) {
9452            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9453                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9454                    reason != null ? reason : "kill uid");
9455        }
9456    }
9457
9458    @Override
9459    public boolean killProcessesBelowForeground(String reason) {
9460        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9461            throw new SecurityException("killProcessesBelowForeground() only available to system");
9462        }
9463
9464        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9465    }
9466
9467    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9468        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9469            throw new SecurityException("killProcessesBelowAdj() only available to system");
9470        }
9471
9472        boolean killed = false;
9473        synchronized (mPidsSelfLocked) {
9474            final int size = mPidsSelfLocked.size();
9475            for (int i = 0; i < size; i++) {
9476                final int pid = mPidsSelfLocked.keyAt(i);
9477                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9478                if (proc == null) continue;
9479
9480                final int adj = proc.setAdj;
9481                if (adj > belowAdj && !proc.killedByAm) {
9482                    killUnneededProcessLocked(proc, reason);
9483                    killed = true;
9484                }
9485            }
9486        }
9487        return killed;
9488    }
9489
9490    @Override
9491    public void hang(final IBinder who, boolean allowRestart) {
9492        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9493                != PackageManager.PERMISSION_GRANTED) {
9494            throw new SecurityException("Requires permission "
9495                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9496        }
9497
9498        final IBinder.DeathRecipient death = new DeathRecipient() {
9499            @Override
9500            public void binderDied() {
9501                synchronized (this) {
9502                    notifyAll();
9503                }
9504            }
9505        };
9506
9507        try {
9508            who.linkToDeath(death, 0);
9509        } catch (RemoteException e) {
9510            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9511            return;
9512        }
9513
9514        synchronized (this) {
9515            Watchdog.getInstance().setAllowRestart(allowRestart);
9516            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9517            synchronized (death) {
9518                while (who.isBinderAlive()) {
9519                    try {
9520                        death.wait();
9521                    } catch (InterruptedException e) {
9522                    }
9523                }
9524            }
9525            Watchdog.getInstance().setAllowRestart(true);
9526        }
9527    }
9528
9529    @Override
9530    public void restart() {
9531        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9532                != PackageManager.PERMISSION_GRANTED) {
9533            throw new SecurityException("Requires permission "
9534                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9535        }
9536
9537        Log.i(TAG, "Sending shutdown broadcast...");
9538
9539        BroadcastReceiver br = new BroadcastReceiver() {
9540            @Override public void onReceive(Context context, Intent intent) {
9541                // Now the broadcast is done, finish up the low-level shutdown.
9542                Log.i(TAG, "Shutting down activity manager...");
9543                shutdown(10000);
9544                Log.i(TAG, "Shutdown complete, restarting!");
9545                Process.killProcess(Process.myPid());
9546                System.exit(10);
9547            }
9548        };
9549
9550        // First send the high-level shut down broadcast.
9551        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9552        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9553        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9554        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9555        mContext.sendOrderedBroadcastAsUser(intent,
9556                UserHandle.ALL, null, br, mHandler, 0, null, null);
9557        */
9558        br.onReceive(mContext, intent);
9559    }
9560
9561    private long getLowRamTimeSinceIdle(long now) {
9562        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9563    }
9564
9565    @Override
9566    public void performIdleMaintenance() {
9567        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9568                != PackageManager.PERMISSION_GRANTED) {
9569            throw new SecurityException("Requires permission "
9570                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9571        }
9572
9573        synchronized (this) {
9574            final long now = SystemClock.uptimeMillis();
9575            final long timeSinceLastIdle = now - mLastIdleTime;
9576            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9577            mLastIdleTime = now;
9578            mLowRamTimeSinceLastIdle = 0;
9579            if (mLowRamStartTime != 0) {
9580                mLowRamStartTime = now;
9581            }
9582
9583            StringBuilder sb = new StringBuilder(128);
9584            sb.append("Idle maintenance over ");
9585            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9586            sb.append(" low RAM for ");
9587            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9588            Slog.i(TAG, sb.toString());
9589
9590            // If at least 1/3 of our time since the last idle period has been spent
9591            // with RAM low, then we want to kill processes.
9592            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9593
9594            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9595                ProcessRecord proc = mLruProcesses.get(i);
9596                if (proc.notCachedSinceIdle) {
9597                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9598                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9599                        if (doKilling && proc.initialIdlePss != 0
9600                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9601                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9602                                    + " from " + proc.initialIdlePss + ")");
9603                        }
9604                    }
9605                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9606                    proc.notCachedSinceIdle = true;
9607                    proc.initialIdlePss = 0;
9608                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9609                            isSleeping(), now);
9610                }
9611            }
9612
9613            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9614            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9615        }
9616    }
9617
9618    private void retrieveSettings() {
9619        final ContentResolver resolver = mContext.getContentResolver();
9620        String debugApp = Settings.Global.getString(
9621            resolver, Settings.Global.DEBUG_APP);
9622        boolean waitForDebugger = Settings.Global.getInt(
9623            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9624        boolean alwaysFinishActivities = Settings.Global.getInt(
9625            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9626        boolean forceRtl = Settings.Global.getInt(
9627                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9628        // Transfer any global setting for forcing RTL layout, into a System Property
9629        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9630
9631        Configuration configuration = new Configuration();
9632        Settings.System.getConfiguration(resolver, configuration);
9633        if (forceRtl) {
9634            // This will take care of setting the correct layout direction flags
9635            configuration.setLayoutDirection(configuration.locale);
9636        }
9637
9638        synchronized (this) {
9639            mDebugApp = mOrigDebugApp = debugApp;
9640            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9641            mAlwaysFinishActivities = alwaysFinishActivities;
9642            // This happens before any activities are started, so we can
9643            // change mConfiguration in-place.
9644            updateConfigurationLocked(configuration, null, false, true);
9645            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9646        }
9647    }
9648
9649    public boolean testIsSystemReady() {
9650        // no need to synchronize(this) just to read & return the value
9651        return mSystemReady;
9652    }
9653
9654    private static File getCalledPreBootReceiversFile() {
9655        File dataDir = Environment.getDataDirectory();
9656        File systemDir = new File(dataDir, "system");
9657        File fname = new File(systemDir, "called_pre_boots.dat");
9658        return fname;
9659    }
9660
9661    static final int LAST_DONE_VERSION = 10000;
9662
9663    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9664        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9665        File file = getCalledPreBootReceiversFile();
9666        FileInputStream fis = null;
9667        try {
9668            fis = new FileInputStream(file);
9669            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9670            int fvers = dis.readInt();
9671            if (fvers == LAST_DONE_VERSION) {
9672                String vers = dis.readUTF();
9673                String codename = dis.readUTF();
9674                String build = dis.readUTF();
9675                if (android.os.Build.VERSION.RELEASE.equals(vers)
9676                        && android.os.Build.VERSION.CODENAME.equals(codename)
9677                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9678                    int num = dis.readInt();
9679                    while (num > 0) {
9680                        num--;
9681                        String pkg = dis.readUTF();
9682                        String cls = dis.readUTF();
9683                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9684                    }
9685                }
9686            }
9687        } catch (FileNotFoundException e) {
9688        } catch (IOException e) {
9689            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9690        } finally {
9691            if (fis != null) {
9692                try {
9693                    fis.close();
9694                } catch (IOException e) {
9695                }
9696            }
9697        }
9698        return lastDoneReceivers;
9699    }
9700
9701    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9702        File file = getCalledPreBootReceiversFile();
9703        FileOutputStream fos = null;
9704        DataOutputStream dos = null;
9705        try {
9706            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9707            fos = new FileOutputStream(file);
9708            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9709            dos.writeInt(LAST_DONE_VERSION);
9710            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9711            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9712            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9713            dos.writeInt(list.size());
9714            for (int i=0; i<list.size(); i++) {
9715                dos.writeUTF(list.get(i).getPackageName());
9716                dos.writeUTF(list.get(i).getClassName());
9717            }
9718        } catch (IOException e) {
9719            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9720            file.delete();
9721        } finally {
9722            FileUtils.sync(fos);
9723            if (dos != null) {
9724                try {
9725                    dos.close();
9726                } catch (IOException e) {
9727                    // TODO Auto-generated catch block
9728                    e.printStackTrace();
9729                }
9730            }
9731        }
9732    }
9733
9734    public void systemReady(final Runnable goingCallback) {
9735        synchronized(this) {
9736            if (mSystemReady) {
9737                if (goingCallback != null) goingCallback.run();
9738                return;
9739            }
9740
9741            if (mRecentTasks == null) {
9742                mRecentTasks = mTaskPersister.restoreTasksLocked();
9743                if (!mRecentTasks.isEmpty()) {
9744                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9745                }
9746                mTaskPersister.startPersisting();
9747            }
9748
9749            // Check to see if there are any update receivers to run.
9750            if (!mDidUpdate) {
9751                if (mWaitingUpdate) {
9752                    return;
9753                }
9754                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9755                List<ResolveInfo> ris = null;
9756                try {
9757                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9758                            intent, null, 0, 0);
9759                } catch (RemoteException e) {
9760                }
9761                if (ris != null) {
9762                    for (int i=ris.size()-1; i>=0; i--) {
9763                        if ((ris.get(i).activityInfo.applicationInfo.flags
9764                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9765                            ris.remove(i);
9766                        }
9767                    }
9768                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9769
9770                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9771
9772                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9773                    for (int i=0; i<ris.size(); i++) {
9774                        ActivityInfo ai = ris.get(i).activityInfo;
9775                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9776                        if (lastDoneReceivers.contains(comp)) {
9777                            // We already did the pre boot receiver for this app with the current
9778                            // platform version, so don't do it again...
9779                            ris.remove(i);
9780                            i--;
9781                            // ...however, do keep it as one that has been done, so we don't
9782                            // forget about it when rewriting the file of last done receivers.
9783                            doneReceivers.add(comp);
9784                        }
9785                    }
9786
9787                    final int[] users = getUsersLocked();
9788                    for (int i=0; i<ris.size(); i++) {
9789                        ActivityInfo ai = ris.get(i).activityInfo;
9790                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9791                        doneReceivers.add(comp);
9792                        intent.setComponent(comp);
9793                        for (int j=0; j<users.length; j++) {
9794                            IIntentReceiver finisher = null;
9795                            if (i == ris.size()-1 && j == users.length-1) {
9796                                finisher = new IIntentReceiver.Stub() {
9797                                    public void performReceive(Intent intent, int resultCode,
9798                                            String data, Bundle extras, boolean ordered,
9799                                            boolean sticky, int sendingUser) {
9800                                        // The raw IIntentReceiver interface is called
9801                                        // with the AM lock held, so redispatch to
9802                                        // execute our code without the lock.
9803                                        mHandler.post(new Runnable() {
9804                                            public void run() {
9805                                                synchronized (ActivityManagerService.this) {
9806                                                    mDidUpdate = true;
9807                                                }
9808                                                writeLastDonePreBootReceivers(doneReceivers);
9809                                                showBootMessage(mContext.getText(
9810                                                        R.string.android_upgrading_complete),
9811                                                        false);
9812                                                systemReady(goingCallback);
9813                                            }
9814                                        });
9815                                    }
9816                                };
9817                            }
9818                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9819                                    + " for user " + users[j]);
9820                            broadcastIntentLocked(null, null, intent, null, finisher,
9821                                    0, null, null, null, AppOpsManager.OP_NONE,
9822                                    true, false, MY_PID, Process.SYSTEM_UID,
9823                                    users[j]);
9824                            if (finisher != null) {
9825                                mWaitingUpdate = true;
9826                            }
9827                        }
9828                    }
9829                }
9830                if (mWaitingUpdate) {
9831                    return;
9832                }
9833                mDidUpdate = true;
9834            }
9835
9836            mAppOpsService.systemReady();
9837            mUsageStatsService.systemReady();
9838            mSystemReady = true;
9839        }
9840
9841        ArrayList<ProcessRecord> procsToKill = null;
9842        synchronized(mPidsSelfLocked) {
9843            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9844                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9845                if (!isAllowedWhileBooting(proc.info)){
9846                    if (procsToKill == null) {
9847                        procsToKill = new ArrayList<ProcessRecord>();
9848                    }
9849                    procsToKill.add(proc);
9850                }
9851            }
9852        }
9853
9854        synchronized(this) {
9855            if (procsToKill != null) {
9856                for (int i=procsToKill.size()-1; i>=0; i--) {
9857                    ProcessRecord proc = procsToKill.get(i);
9858                    Slog.i(TAG, "Removing system update proc: " + proc);
9859                    removeProcessLocked(proc, true, false, "system update done");
9860                }
9861            }
9862
9863            // Now that we have cleaned up any update processes, we
9864            // are ready to start launching real processes and know that
9865            // we won't trample on them any more.
9866            mProcessesReady = true;
9867        }
9868
9869        Slog.i(TAG, "System now ready");
9870        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9871            SystemClock.uptimeMillis());
9872
9873        synchronized(this) {
9874            // Make sure we have no pre-ready processes sitting around.
9875
9876            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9877                ResolveInfo ri = mContext.getPackageManager()
9878                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9879                                STOCK_PM_FLAGS);
9880                CharSequence errorMsg = null;
9881                if (ri != null) {
9882                    ActivityInfo ai = ri.activityInfo;
9883                    ApplicationInfo app = ai.applicationInfo;
9884                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9885                        mTopAction = Intent.ACTION_FACTORY_TEST;
9886                        mTopData = null;
9887                        mTopComponent = new ComponentName(app.packageName,
9888                                ai.name);
9889                    } else {
9890                        errorMsg = mContext.getResources().getText(
9891                                com.android.internal.R.string.factorytest_not_system);
9892                    }
9893                } else {
9894                    errorMsg = mContext.getResources().getText(
9895                            com.android.internal.R.string.factorytest_no_action);
9896                }
9897                if (errorMsg != null) {
9898                    mTopAction = null;
9899                    mTopData = null;
9900                    mTopComponent = null;
9901                    Message msg = Message.obtain();
9902                    msg.what = SHOW_FACTORY_ERROR_MSG;
9903                    msg.getData().putCharSequence("msg", errorMsg);
9904                    mHandler.sendMessage(msg);
9905                }
9906            }
9907        }
9908
9909        retrieveSettings();
9910
9911        synchronized (this) {
9912            readGrantedUriPermissionsLocked();
9913        }
9914
9915        if (goingCallback != null) goingCallback.run();
9916
9917        mSystemServiceManager.startUser(mCurrentUserId);
9918
9919        synchronized (this) {
9920            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9921                try {
9922                    List apps = AppGlobals.getPackageManager().
9923                        getPersistentApplications(STOCK_PM_FLAGS);
9924                    if (apps != null) {
9925                        int N = apps.size();
9926                        int i;
9927                        for (i=0; i<N; i++) {
9928                            ApplicationInfo info
9929                                = (ApplicationInfo)apps.get(i);
9930                            if (info != null &&
9931                                    !info.packageName.equals("android")) {
9932                                addAppLocked(info, false, null /* ABI override */);
9933                            }
9934                        }
9935                    }
9936                } catch (RemoteException ex) {
9937                    // pm is in same process, this will never happen.
9938                }
9939            }
9940
9941            // Start up initial activity.
9942            mBooting = true;
9943
9944            try {
9945                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9946                    Message msg = Message.obtain();
9947                    msg.what = SHOW_UID_ERROR_MSG;
9948                    mHandler.sendMessage(msg);
9949                }
9950            } catch (RemoteException e) {
9951            }
9952
9953            long ident = Binder.clearCallingIdentity();
9954            try {
9955                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9956                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9957                        | Intent.FLAG_RECEIVER_FOREGROUND);
9958                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9959                broadcastIntentLocked(null, null, intent,
9960                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9961                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9962                intent = new Intent(Intent.ACTION_USER_STARTING);
9963                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9964                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9965                broadcastIntentLocked(null, null, intent,
9966                        null, new IIntentReceiver.Stub() {
9967                            @Override
9968                            public void performReceive(Intent intent, int resultCode, String data,
9969                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9970                                    throws RemoteException {
9971                            }
9972                        }, 0, null, null,
9973                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9974                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9975            } catch (Throwable t) {
9976                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9977            } finally {
9978                Binder.restoreCallingIdentity(ident);
9979            }
9980            mStackSupervisor.resumeTopActivitiesLocked();
9981            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9982        }
9983    }
9984
9985    private boolean makeAppCrashingLocked(ProcessRecord app,
9986            String shortMsg, String longMsg, String stackTrace) {
9987        app.crashing = true;
9988        app.crashingReport = generateProcessError(app,
9989                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9990        startAppProblemLocked(app);
9991        app.stopFreezingAllLocked();
9992        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9993    }
9994
9995    private void makeAppNotRespondingLocked(ProcessRecord app,
9996            String activity, String shortMsg, String longMsg) {
9997        app.notResponding = true;
9998        app.notRespondingReport = generateProcessError(app,
9999                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10000                activity, shortMsg, longMsg, null);
10001        startAppProblemLocked(app);
10002        app.stopFreezingAllLocked();
10003    }
10004
10005    /**
10006     * Generate a process error record, suitable for attachment to a ProcessRecord.
10007     *
10008     * @param app The ProcessRecord in which the error occurred.
10009     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10010     *                      ActivityManager.AppErrorStateInfo
10011     * @param activity The activity associated with the crash, if known.
10012     * @param shortMsg Short message describing the crash.
10013     * @param longMsg Long message describing the crash.
10014     * @param stackTrace Full crash stack trace, may be null.
10015     *
10016     * @return Returns a fully-formed AppErrorStateInfo record.
10017     */
10018    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10019            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10020        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10021
10022        report.condition = condition;
10023        report.processName = app.processName;
10024        report.pid = app.pid;
10025        report.uid = app.info.uid;
10026        report.tag = activity;
10027        report.shortMsg = shortMsg;
10028        report.longMsg = longMsg;
10029        report.stackTrace = stackTrace;
10030
10031        return report;
10032    }
10033
10034    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10035        synchronized (this) {
10036            app.crashing = false;
10037            app.crashingReport = null;
10038            app.notResponding = false;
10039            app.notRespondingReport = null;
10040            if (app.anrDialog == fromDialog) {
10041                app.anrDialog = null;
10042            }
10043            if (app.waitDialog == fromDialog) {
10044                app.waitDialog = null;
10045            }
10046            if (app.pid > 0 && app.pid != MY_PID) {
10047                handleAppCrashLocked(app, null, null, null);
10048                killUnneededProcessLocked(app, "user request after error");
10049            }
10050        }
10051    }
10052
10053    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10054            String stackTrace) {
10055        long now = SystemClock.uptimeMillis();
10056
10057        Long crashTime;
10058        if (!app.isolated) {
10059            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10060        } else {
10061            crashTime = null;
10062        }
10063        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10064            // This process loses!
10065            Slog.w(TAG, "Process " + app.info.processName
10066                    + " has crashed too many times: killing!");
10067            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10068                    app.userId, app.info.processName, app.uid);
10069            mStackSupervisor.handleAppCrashLocked(app);
10070            if (!app.persistent) {
10071                // We don't want to start this process again until the user
10072                // explicitly does so...  but for persistent process, we really
10073                // need to keep it running.  If a persistent process is actually
10074                // repeatedly crashing, then badness for everyone.
10075                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10076                        app.info.processName);
10077                if (!app.isolated) {
10078                    // XXX We don't have a way to mark isolated processes
10079                    // as bad, since they don't have a peristent identity.
10080                    mBadProcesses.put(app.info.processName, app.uid,
10081                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10082                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10083                }
10084                app.bad = true;
10085                app.removed = true;
10086                // Don't let services in this process be restarted and potentially
10087                // annoy the user repeatedly.  Unless it is persistent, since those
10088                // processes run critical code.
10089                removeProcessLocked(app, false, false, "crash");
10090                mStackSupervisor.resumeTopActivitiesLocked();
10091                return false;
10092            }
10093            mStackSupervisor.resumeTopActivitiesLocked();
10094        } else {
10095            mStackSupervisor.finishTopRunningActivityLocked(app);
10096        }
10097
10098        // Bump up the crash count of any services currently running in the proc.
10099        for (int i=app.services.size()-1; i>=0; i--) {
10100            // Any services running in the application need to be placed
10101            // back in the pending list.
10102            ServiceRecord sr = app.services.valueAt(i);
10103            sr.crashCount++;
10104        }
10105
10106        // If the crashing process is what we consider to be the "home process" and it has been
10107        // replaced by a third-party app, clear the package preferred activities from packages
10108        // with a home activity running in the process to prevent a repeatedly crashing app
10109        // from blocking the user to manually clear the list.
10110        final ArrayList<ActivityRecord> activities = app.activities;
10111        if (app == mHomeProcess && activities.size() > 0
10112                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10113            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10114                final ActivityRecord r = activities.get(activityNdx);
10115                if (r.isHomeActivity()) {
10116                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10117                    try {
10118                        ActivityThread.getPackageManager()
10119                                .clearPackagePreferredActivities(r.packageName);
10120                    } catch (RemoteException c) {
10121                        // pm is in same process, this will never happen.
10122                    }
10123                }
10124            }
10125        }
10126
10127        if (!app.isolated) {
10128            // XXX Can't keep track of crash times for isolated processes,
10129            // because they don't have a perisistent identity.
10130            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10131        }
10132
10133        return true;
10134    }
10135
10136    void startAppProblemLocked(ProcessRecord app) {
10137        if (app.userId == mCurrentUserId) {
10138            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10139                    mContext, app.info.packageName, app.info.flags);
10140        } else {
10141            // If this app is not running under the current user, then we
10142            // can't give it a report button because that would require
10143            // launching the report UI under a different user.
10144            app.errorReportReceiver = null;
10145        }
10146        skipCurrentReceiverLocked(app);
10147    }
10148
10149    void skipCurrentReceiverLocked(ProcessRecord app) {
10150        for (BroadcastQueue queue : mBroadcastQueues) {
10151            queue.skipCurrentReceiverLocked(app);
10152        }
10153    }
10154
10155    /**
10156     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10157     * The application process will exit immediately after this call returns.
10158     * @param app object of the crashing app, null for the system server
10159     * @param crashInfo describing the exception
10160     */
10161    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10162        ProcessRecord r = findAppProcess(app, "Crash");
10163        final String processName = app == null ? "system_server"
10164                : (r == null ? "unknown" : r.processName);
10165
10166        handleApplicationCrashInner("crash", r, processName, crashInfo);
10167    }
10168
10169    /* Native crash reporting uses this inner version because it needs to be somewhat
10170     * decoupled from the AM-managed cleanup lifecycle
10171     */
10172    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10173            ApplicationErrorReport.CrashInfo crashInfo) {
10174        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10175                UserHandle.getUserId(Binder.getCallingUid()), processName,
10176                r == null ? -1 : r.info.flags,
10177                crashInfo.exceptionClassName,
10178                crashInfo.exceptionMessage,
10179                crashInfo.throwFileName,
10180                crashInfo.throwLineNumber);
10181
10182        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10183
10184        crashApplication(r, crashInfo);
10185    }
10186
10187    public void handleApplicationStrictModeViolation(
10188            IBinder app,
10189            int violationMask,
10190            StrictMode.ViolationInfo info) {
10191        ProcessRecord r = findAppProcess(app, "StrictMode");
10192        if (r == null) {
10193            return;
10194        }
10195
10196        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10197            Integer stackFingerprint = info.hashCode();
10198            boolean logIt = true;
10199            synchronized (mAlreadyLoggedViolatedStacks) {
10200                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10201                    logIt = false;
10202                    // TODO: sub-sample into EventLog for these, with
10203                    // the info.durationMillis?  Then we'd get
10204                    // the relative pain numbers, without logging all
10205                    // the stack traces repeatedly.  We'd want to do
10206                    // likewise in the client code, which also does
10207                    // dup suppression, before the Binder call.
10208                } else {
10209                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10210                        mAlreadyLoggedViolatedStacks.clear();
10211                    }
10212                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10213                }
10214            }
10215            if (logIt) {
10216                logStrictModeViolationToDropBox(r, info);
10217            }
10218        }
10219
10220        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10221            AppErrorResult result = new AppErrorResult();
10222            synchronized (this) {
10223                final long origId = Binder.clearCallingIdentity();
10224
10225                Message msg = Message.obtain();
10226                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10227                HashMap<String, Object> data = new HashMap<String, Object>();
10228                data.put("result", result);
10229                data.put("app", r);
10230                data.put("violationMask", violationMask);
10231                data.put("info", info);
10232                msg.obj = data;
10233                mHandler.sendMessage(msg);
10234
10235                Binder.restoreCallingIdentity(origId);
10236            }
10237            int res = result.get();
10238            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10239        }
10240    }
10241
10242    // Depending on the policy in effect, there could be a bunch of
10243    // these in quick succession so we try to batch these together to
10244    // minimize disk writes, number of dropbox entries, and maximize
10245    // compression, by having more fewer, larger records.
10246    private void logStrictModeViolationToDropBox(
10247            ProcessRecord process,
10248            StrictMode.ViolationInfo info) {
10249        if (info == null) {
10250            return;
10251        }
10252        final boolean isSystemApp = process == null ||
10253                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10254                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10255        final String processName = process == null ? "unknown" : process.processName;
10256        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10257        final DropBoxManager dbox = (DropBoxManager)
10258                mContext.getSystemService(Context.DROPBOX_SERVICE);
10259
10260        // Exit early if the dropbox isn't configured to accept this report type.
10261        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10262
10263        boolean bufferWasEmpty;
10264        boolean needsFlush;
10265        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10266        synchronized (sb) {
10267            bufferWasEmpty = sb.length() == 0;
10268            appendDropBoxProcessHeaders(process, processName, sb);
10269            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10270            sb.append("System-App: ").append(isSystemApp).append("\n");
10271            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10272            if (info.violationNumThisLoop != 0) {
10273                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10274            }
10275            if (info.numAnimationsRunning != 0) {
10276                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10277            }
10278            if (info.broadcastIntentAction != null) {
10279                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10280            }
10281            if (info.durationMillis != -1) {
10282                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10283            }
10284            if (info.numInstances != -1) {
10285                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10286            }
10287            if (info.tags != null) {
10288                for (String tag : info.tags) {
10289                    sb.append("Span-Tag: ").append(tag).append("\n");
10290                }
10291            }
10292            sb.append("\n");
10293            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10294                sb.append(info.crashInfo.stackTrace);
10295            }
10296            sb.append("\n");
10297
10298            // Only buffer up to ~64k.  Various logging bits truncate
10299            // things at 128k.
10300            needsFlush = (sb.length() > 64 * 1024);
10301        }
10302
10303        // Flush immediately if the buffer's grown too large, or this
10304        // is a non-system app.  Non-system apps are isolated with a
10305        // different tag & policy and not batched.
10306        //
10307        // Batching is useful during internal testing with
10308        // StrictMode settings turned up high.  Without batching,
10309        // thousands of separate files could be created on boot.
10310        if (!isSystemApp || needsFlush) {
10311            new Thread("Error dump: " + dropboxTag) {
10312                @Override
10313                public void run() {
10314                    String report;
10315                    synchronized (sb) {
10316                        report = sb.toString();
10317                        sb.delete(0, sb.length());
10318                        sb.trimToSize();
10319                    }
10320                    if (report.length() != 0) {
10321                        dbox.addText(dropboxTag, report);
10322                    }
10323                }
10324            }.start();
10325            return;
10326        }
10327
10328        // System app batching:
10329        if (!bufferWasEmpty) {
10330            // An existing dropbox-writing thread is outstanding, so
10331            // we don't need to start it up.  The existing thread will
10332            // catch the buffer appends we just did.
10333            return;
10334        }
10335
10336        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10337        // (After this point, we shouldn't access AMS internal data structures.)
10338        new Thread("Error dump: " + dropboxTag) {
10339            @Override
10340            public void run() {
10341                // 5 second sleep to let stacks arrive and be batched together
10342                try {
10343                    Thread.sleep(5000);  // 5 seconds
10344                } catch (InterruptedException e) {}
10345
10346                String errorReport;
10347                synchronized (mStrictModeBuffer) {
10348                    errorReport = mStrictModeBuffer.toString();
10349                    if (errorReport.length() == 0) {
10350                        return;
10351                    }
10352                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10353                    mStrictModeBuffer.trimToSize();
10354                }
10355                dbox.addText(dropboxTag, errorReport);
10356            }
10357        }.start();
10358    }
10359
10360    /**
10361     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10362     * @param app object of the crashing app, null for the system server
10363     * @param tag reported by the caller
10364     * @param crashInfo describing the context of the error
10365     * @return true if the process should exit immediately (WTF is fatal)
10366     */
10367    public boolean handleApplicationWtf(IBinder app, String tag,
10368            ApplicationErrorReport.CrashInfo crashInfo) {
10369        ProcessRecord r = findAppProcess(app, "WTF");
10370        final String processName = app == null ? "system_server"
10371                : (r == null ? "unknown" : r.processName);
10372
10373        EventLog.writeEvent(EventLogTags.AM_WTF,
10374                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10375                processName,
10376                r == null ? -1 : r.info.flags,
10377                tag, crashInfo.exceptionMessage);
10378
10379        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10380
10381        if (r != null && r.pid != Process.myPid() &&
10382                Settings.Global.getInt(mContext.getContentResolver(),
10383                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10384            crashApplication(r, crashInfo);
10385            return true;
10386        } else {
10387            return false;
10388        }
10389    }
10390
10391    /**
10392     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10393     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10394     */
10395    private ProcessRecord findAppProcess(IBinder app, String reason) {
10396        if (app == null) {
10397            return null;
10398        }
10399
10400        synchronized (this) {
10401            final int NP = mProcessNames.getMap().size();
10402            for (int ip=0; ip<NP; ip++) {
10403                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10404                final int NA = apps.size();
10405                for (int ia=0; ia<NA; ia++) {
10406                    ProcessRecord p = apps.valueAt(ia);
10407                    if (p.thread != null && p.thread.asBinder() == app) {
10408                        return p;
10409                    }
10410                }
10411            }
10412
10413            Slog.w(TAG, "Can't find mystery application for " + reason
10414                    + " from pid=" + Binder.getCallingPid()
10415                    + " uid=" + Binder.getCallingUid() + ": " + app);
10416            return null;
10417        }
10418    }
10419
10420    /**
10421     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10422     * to append various headers to the dropbox log text.
10423     */
10424    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10425            StringBuilder sb) {
10426        // Watchdog thread ends up invoking this function (with
10427        // a null ProcessRecord) to add the stack file to dropbox.
10428        // Do not acquire a lock on this (am) in such cases, as it
10429        // could cause a potential deadlock, if and when watchdog
10430        // is invoked due to unavailability of lock on am and it
10431        // would prevent watchdog from killing system_server.
10432        if (process == null) {
10433            sb.append("Process: ").append(processName).append("\n");
10434            return;
10435        }
10436        // Note: ProcessRecord 'process' is guarded by the service
10437        // instance.  (notably process.pkgList, which could otherwise change
10438        // concurrently during execution of this method)
10439        synchronized (this) {
10440            sb.append("Process: ").append(processName).append("\n");
10441            int flags = process.info.flags;
10442            IPackageManager pm = AppGlobals.getPackageManager();
10443            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10444            for (int ip=0; ip<process.pkgList.size(); ip++) {
10445                String pkg = process.pkgList.keyAt(ip);
10446                sb.append("Package: ").append(pkg);
10447                try {
10448                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10449                    if (pi != null) {
10450                        sb.append(" v").append(pi.versionCode);
10451                        if (pi.versionName != null) {
10452                            sb.append(" (").append(pi.versionName).append(")");
10453                        }
10454                    }
10455                } catch (RemoteException e) {
10456                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10457                }
10458                sb.append("\n");
10459            }
10460        }
10461    }
10462
10463    private static String processClass(ProcessRecord process) {
10464        if (process == null || process.pid == MY_PID) {
10465            return "system_server";
10466        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10467            return "system_app";
10468        } else {
10469            return "data_app";
10470        }
10471    }
10472
10473    /**
10474     * Write a description of an error (crash, WTF, ANR) to the drop box.
10475     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10476     * @param process which caused the error, null means the system server
10477     * @param activity which triggered the error, null if unknown
10478     * @param parent activity related to the error, null if unknown
10479     * @param subject line related to the error, null if absent
10480     * @param report in long form describing the error, null if absent
10481     * @param logFile to include in the report, null if none
10482     * @param crashInfo giving an application stack trace, null if absent
10483     */
10484    public void addErrorToDropBox(String eventType,
10485            ProcessRecord process, String processName, ActivityRecord activity,
10486            ActivityRecord parent, String subject,
10487            final String report, final File logFile,
10488            final ApplicationErrorReport.CrashInfo crashInfo) {
10489        // NOTE -- this must never acquire the ActivityManagerService lock,
10490        // otherwise the watchdog may be prevented from resetting the system.
10491
10492        final String dropboxTag = processClass(process) + "_" + eventType;
10493        final DropBoxManager dbox = (DropBoxManager)
10494                mContext.getSystemService(Context.DROPBOX_SERVICE);
10495
10496        // Exit early if the dropbox isn't configured to accept this report type.
10497        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10498
10499        final StringBuilder sb = new StringBuilder(1024);
10500        appendDropBoxProcessHeaders(process, processName, sb);
10501        if (activity != null) {
10502            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10503        }
10504        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10505            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10506        }
10507        if (parent != null && parent != activity) {
10508            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10509        }
10510        if (subject != null) {
10511            sb.append("Subject: ").append(subject).append("\n");
10512        }
10513        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10514        if (Debug.isDebuggerConnected()) {
10515            sb.append("Debugger: Connected\n");
10516        }
10517        sb.append("\n");
10518
10519        // Do the rest in a worker thread to avoid blocking the caller on I/O
10520        // (After this point, we shouldn't access AMS internal data structures.)
10521        Thread worker = new Thread("Error dump: " + dropboxTag) {
10522            @Override
10523            public void run() {
10524                if (report != null) {
10525                    sb.append(report);
10526                }
10527                if (logFile != null) {
10528                    try {
10529                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10530                                    "\n\n[[TRUNCATED]]"));
10531                    } catch (IOException e) {
10532                        Slog.e(TAG, "Error reading " + logFile, e);
10533                    }
10534                }
10535                if (crashInfo != null && crashInfo.stackTrace != null) {
10536                    sb.append(crashInfo.stackTrace);
10537                }
10538
10539                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10540                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10541                if (lines > 0) {
10542                    sb.append("\n");
10543
10544                    // Merge several logcat streams, and take the last N lines
10545                    InputStreamReader input = null;
10546                    try {
10547                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10548                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10549                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10550
10551                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10552                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10553                        input = new InputStreamReader(logcat.getInputStream());
10554
10555                        int num;
10556                        char[] buf = new char[8192];
10557                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10558                    } catch (IOException e) {
10559                        Slog.e(TAG, "Error running logcat", e);
10560                    } finally {
10561                        if (input != null) try { input.close(); } catch (IOException e) {}
10562                    }
10563                }
10564
10565                dbox.addText(dropboxTag, sb.toString());
10566            }
10567        };
10568
10569        if (process == null) {
10570            // If process is null, we are being called from some internal code
10571            // and may be about to die -- run this synchronously.
10572            worker.run();
10573        } else {
10574            worker.start();
10575        }
10576    }
10577
10578    /**
10579     * Bring up the "unexpected error" dialog box for a crashing app.
10580     * Deal with edge cases (intercepts from instrumented applications,
10581     * ActivityController, error intent receivers, that sort of thing).
10582     * @param r the application crashing
10583     * @param crashInfo describing the failure
10584     */
10585    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10586        long timeMillis = System.currentTimeMillis();
10587        String shortMsg = crashInfo.exceptionClassName;
10588        String longMsg = crashInfo.exceptionMessage;
10589        String stackTrace = crashInfo.stackTrace;
10590        if (shortMsg != null && longMsg != null) {
10591            longMsg = shortMsg + ": " + longMsg;
10592        } else if (shortMsg != null) {
10593            longMsg = shortMsg;
10594        }
10595
10596        AppErrorResult result = new AppErrorResult();
10597        synchronized (this) {
10598            if (mController != null) {
10599                try {
10600                    String name = r != null ? r.processName : null;
10601                    int pid = r != null ? r.pid : Binder.getCallingPid();
10602                    if (!mController.appCrashed(name, pid,
10603                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10604                        Slog.w(TAG, "Force-killing crashed app " + name
10605                                + " at watcher's request");
10606                        Process.killProcess(pid);
10607                        return;
10608                    }
10609                } catch (RemoteException e) {
10610                    mController = null;
10611                    Watchdog.getInstance().setActivityController(null);
10612                }
10613            }
10614
10615            final long origId = Binder.clearCallingIdentity();
10616
10617            // If this process is running instrumentation, finish it.
10618            if (r != null && r.instrumentationClass != null) {
10619                Slog.w(TAG, "Error in app " + r.processName
10620                      + " running instrumentation " + r.instrumentationClass + ":");
10621                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10622                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10623                Bundle info = new Bundle();
10624                info.putString("shortMsg", shortMsg);
10625                info.putString("longMsg", longMsg);
10626                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10627                Binder.restoreCallingIdentity(origId);
10628                return;
10629            }
10630
10631            // If we can't identify the process or it's already exceeded its crash quota,
10632            // quit right away without showing a crash dialog.
10633            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10634                Binder.restoreCallingIdentity(origId);
10635                return;
10636            }
10637
10638            Message msg = Message.obtain();
10639            msg.what = SHOW_ERROR_MSG;
10640            HashMap data = new HashMap();
10641            data.put("result", result);
10642            data.put("app", r);
10643            msg.obj = data;
10644            mHandler.sendMessage(msg);
10645
10646            Binder.restoreCallingIdentity(origId);
10647        }
10648
10649        int res = result.get();
10650
10651        Intent appErrorIntent = null;
10652        synchronized (this) {
10653            if (r != null && !r.isolated) {
10654                // XXX Can't keep track of crash time for isolated processes,
10655                // since they don't have a persistent identity.
10656                mProcessCrashTimes.put(r.info.processName, r.uid,
10657                        SystemClock.uptimeMillis());
10658            }
10659            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10660                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10661            }
10662        }
10663
10664        if (appErrorIntent != null) {
10665            try {
10666                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10667            } catch (ActivityNotFoundException e) {
10668                Slog.w(TAG, "bug report receiver dissappeared", e);
10669            }
10670        }
10671    }
10672
10673    Intent createAppErrorIntentLocked(ProcessRecord r,
10674            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10675        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10676        if (report == null) {
10677            return null;
10678        }
10679        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10680        result.setComponent(r.errorReportReceiver);
10681        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10682        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10683        return result;
10684    }
10685
10686    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10687            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10688        if (r.errorReportReceiver == null) {
10689            return null;
10690        }
10691
10692        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10693            return null;
10694        }
10695
10696        ApplicationErrorReport report = new ApplicationErrorReport();
10697        report.packageName = r.info.packageName;
10698        report.installerPackageName = r.errorReportReceiver.getPackageName();
10699        report.processName = r.processName;
10700        report.time = timeMillis;
10701        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10702
10703        if (r.crashing || r.forceCrashReport) {
10704            report.type = ApplicationErrorReport.TYPE_CRASH;
10705            report.crashInfo = crashInfo;
10706        } else if (r.notResponding) {
10707            report.type = ApplicationErrorReport.TYPE_ANR;
10708            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10709
10710            report.anrInfo.activity = r.notRespondingReport.tag;
10711            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10712            report.anrInfo.info = r.notRespondingReport.longMsg;
10713        }
10714
10715        return report;
10716    }
10717
10718    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10719        enforceNotIsolatedCaller("getProcessesInErrorState");
10720        // assume our apps are happy - lazy create the list
10721        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10722
10723        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10724                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10725        int userId = UserHandle.getUserId(Binder.getCallingUid());
10726
10727        synchronized (this) {
10728
10729            // iterate across all processes
10730            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10731                ProcessRecord app = mLruProcesses.get(i);
10732                if (!allUsers && app.userId != userId) {
10733                    continue;
10734                }
10735                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10736                    // This one's in trouble, so we'll generate a report for it
10737                    // crashes are higher priority (in case there's a crash *and* an anr)
10738                    ActivityManager.ProcessErrorStateInfo report = null;
10739                    if (app.crashing) {
10740                        report = app.crashingReport;
10741                    } else if (app.notResponding) {
10742                        report = app.notRespondingReport;
10743                    }
10744
10745                    if (report != null) {
10746                        if (errList == null) {
10747                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10748                        }
10749                        errList.add(report);
10750                    } else {
10751                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10752                                " crashing = " + app.crashing +
10753                                " notResponding = " + app.notResponding);
10754                    }
10755                }
10756            }
10757        }
10758
10759        return errList;
10760    }
10761
10762    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10763        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10764            if (currApp != null) {
10765                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10766            }
10767            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10768        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10769            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10770        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10771            if (currApp != null) {
10772                currApp.lru = 0;
10773            }
10774            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10775        } else if (adj >= ProcessList.SERVICE_ADJ) {
10776            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10777        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10778            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10779        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10780            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10781        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10782            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10783        } else {
10784            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10785        }
10786    }
10787
10788    private void fillInProcMemInfo(ProcessRecord app,
10789            ActivityManager.RunningAppProcessInfo outInfo) {
10790        outInfo.pid = app.pid;
10791        outInfo.uid = app.info.uid;
10792        if (mHeavyWeightProcess == app) {
10793            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10794        }
10795        if (app.persistent) {
10796            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10797        }
10798        if (app.activities.size() > 0) {
10799            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10800        }
10801        outInfo.lastTrimLevel = app.trimMemoryLevel;
10802        int adj = app.curAdj;
10803        outInfo.importance = oomAdjToImportance(adj, outInfo);
10804        outInfo.importanceReasonCode = app.adjTypeCode;
10805        outInfo.processState = app.curProcState;
10806    }
10807
10808    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10809        enforceNotIsolatedCaller("getRunningAppProcesses");
10810        // Lazy instantiation of list
10811        List<ActivityManager.RunningAppProcessInfo> runList = null;
10812        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10813                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10814        int userId = UserHandle.getUserId(Binder.getCallingUid());
10815        synchronized (this) {
10816            // Iterate across all processes
10817            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10818                ProcessRecord app = mLruProcesses.get(i);
10819                if (!allUsers && app.userId != userId) {
10820                    continue;
10821                }
10822                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10823                    // Generate process state info for running application
10824                    ActivityManager.RunningAppProcessInfo currApp =
10825                        new ActivityManager.RunningAppProcessInfo(app.processName,
10826                                app.pid, app.getPackageList());
10827                    fillInProcMemInfo(app, currApp);
10828                    if (app.adjSource instanceof ProcessRecord) {
10829                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10830                        currApp.importanceReasonImportance = oomAdjToImportance(
10831                                app.adjSourceOom, null);
10832                    } else if (app.adjSource instanceof ActivityRecord) {
10833                        ActivityRecord r = (ActivityRecord)app.adjSource;
10834                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10835                    }
10836                    if (app.adjTarget instanceof ComponentName) {
10837                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10838                    }
10839                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10840                    //        + " lru=" + currApp.lru);
10841                    if (runList == null) {
10842                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10843                    }
10844                    runList.add(currApp);
10845                }
10846            }
10847        }
10848        return runList;
10849    }
10850
10851    public List<ApplicationInfo> getRunningExternalApplications() {
10852        enforceNotIsolatedCaller("getRunningExternalApplications");
10853        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10854        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10855        if (runningApps != null && runningApps.size() > 0) {
10856            Set<String> extList = new HashSet<String>();
10857            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10858                if (app.pkgList != null) {
10859                    for (String pkg : app.pkgList) {
10860                        extList.add(pkg);
10861                    }
10862                }
10863            }
10864            IPackageManager pm = AppGlobals.getPackageManager();
10865            for (String pkg : extList) {
10866                try {
10867                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10868                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10869                        retList.add(info);
10870                    }
10871                } catch (RemoteException e) {
10872                }
10873            }
10874        }
10875        return retList;
10876    }
10877
10878    @Override
10879    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10880        enforceNotIsolatedCaller("getMyMemoryState");
10881        synchronized (this) {
10882            ProcessRecord proc;
10883            synchronized (mPidsSelfLocked) {
10884                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10885            }
10886            fillInProcMemInfo(proc, outInfo);
10887        }
10888    }
10889
10890    @Override
10891    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10892        if (checkCallingPermission(android.Manifest.permission.DUMP)
10893                != PackageManager.PERMISSION_GRANTED) {
10894            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10895                    + Binder.getCallingPid()
10896                    + ", uid=" + Binder.getCallingUid()
10897                    + " without permission "
10898                    + android.Manifest.permission.DUMP);
10899            return;
10900        }
10901
10902        boolean dumpAll = false;
10903        boolean dumpClient = false;
10904        String dumpPackage = null;
10905
10906        int opti = 0;
10907        while (opti < args.length) {
10908            String opt = args[opti];
10909            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10910                break;
10911            }
10912            opti++;
10913            if ("-a".equals(opt)) {
10914                dumpAll = true;
10915            } else if ("-c".equals(opt)) {
10916                dumpClient = true;
10917            } else if ("-h".equals(opt)) {
10918                pw.println("Activity manager dump options:");
10919                pw.println("  [-a] [-c] [-h] [cmd] ...");
10920                pw.println("  cmd may be one of:");
10921                pw.println("    a[ctivities]: activity stack state");
10922                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10923                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10924                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10925                pw.println("    o[om]: out of memory management");
10926                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10927                pw.println("    provider [COMP_SPEC]: provider client-side state");
10928                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10929                pw.println("    service [COMP_SPEC]: service client-side state");
10930                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10931                pw.println("    all: dump all activities");
10932                pw.println("    top: dump the top activity");
10933                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10934                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10935                pw.println("    a partial substring in a component name, a");
10936                pw.println("    hex object identifier.");
10937                pw.println("  -a: include all available server state.");
10938                pw.println("  -c: include client state.");
10939                return;
10940            } else {
10941                pw.println("Unknown argument: " + opt + "; use -h for help");
10942            }
10943        }
10944
10945        long origId = Binder.clearCallingIdentity();
10946        boolean more = false;
10947        // Is the caller requesting to dump a particular piece of data?
10948        if (opti < args.length) {
10949            String cmd = args[opti];
10950            opti++;
10951            if ("activities".equals(cmd) || "a".equals(cmd)) {
10952                synchronized (this) {
10953                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10954                }
10955            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10956                String[] newArgs;
10957                String name;
10958                if (opti >= args.length) {
10959                    name = null;
10960                    newArgs = EMPTY_STRING_ARRAY;
10961                } else {
10962                    name = args[opti];
10963                    opti++;
10964                    newArgs = new String[args.length - opti];
10965                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10966                            args.length - opti);
10967                }
10968                synchronized (this) {
10969                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10970                }
10971            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10972                String[] newArgs;
10973                String name;
10974                if (opti >= args.length) {
10975                    name = null;
10976                    newArgs = EMPTY_STRING_ARRAY;
10977                } else {
10978                    name = args[opti];
10979                    opti++;
10980                    newArgs = new String[args.length - opti];
10981                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10982                            args.length - opti);
10983                }
10984                synchronized (this) {
10985                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10986                }
10987            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10988                String[] newArgs;
10989                String name;
10990                if (opti >= args.length) {
10991                    name = null;
10992                    newArgs = EMPTY_STRING_ARRAY;
10993                } else {
10994                    name = args[opti];
10995                    opti++;
10996                    newArgs = new String[args.length - opti];
10997                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10998                            args.length - opti);
10999                }
11000                synchronized (this) {
11001                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11002                }
11003            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11004                synchronized (this) {
11005                    dumpOomLocked(fd, pw, args, opti, true);
11006                }
11007            } else if ("provider".equals(cmd)) {
11008                String[] newArgs;
11009                String name;
11010                if (opti >= args.length) {
11011                    name = null;
11012                    newArgs = EMPTY_STRING_ARRAY;
11013                } else {
11014                    name = args[opti];
11015                    opti++;
11016                    newArgs = new String[args.length - opti];
11017                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11018                }
11019                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11020                    pw.println("No providers match: " + name);
11021                    pw.println("Use -h for help.");
11022                }
11023            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11024                synchronized (this) {
11025                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11026                }
11027            } else if ("service".equals(cmd)) {
11028                String[] newArgs;
11029                String name;
11030                if (opti >= args.length) {
11031                    name = null;
11032                    newArgs = EMPTY_STRING_ARRAY;
11033                } else {
11034                    name = args[opti];
11035                    opti++;
11036                    newArgs = new String[args.length - opti];
11037                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11038                            args.length - opti);
11039                }
11040                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11041                    pw.println("No services match: " + name);
11042                    pw.println("Use -h for help.");
11043                }
11044            } else if ("package".equals(cmd)) {
11045                String[] newArgs;
11046                if (opti >= args.length) {
11047                    pw.println("package: no package name specified");
11048                    pw.println("Use -h for help.");
11049                } else {
11050                    dumpPackage = args[opti];
11051                    opti++;
11052                    newArgs = new String[args.length - opti];
11053                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11054                            args.length - opti);
11055                    args = newArgs;
11056                    opti = 0;
11057                    more = true;
11058                }
11059            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11060                synchronized (this) {
11061                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11062                }
11063            } else {
11064                // Dumping a single activity?
11065                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11066                    pw.println("Bad activity command, or no activities match: " + cmd);
11067                    pw.println("Use -h for help.");
11068                }
11069            }
11070            if (!more) {
11071                Binder.restoreCallingIdentity(origId);
11072                return;
11073            }
11074        }
11075
11076        // No piece of data specified, dump everything.
11077        synchronized (this) {
11078            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11079            pw.println();
11080            if (dumpAll) {
11081                pw.println("-------------------------------------------------------------------------------");
11082            }
11083            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11084            pw.println();
11085            if (dumpAll) {
11086                pw.println("-------------------------------------------------------------------------------");
11087            }
11088            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11089            pw.println();
11090            if (dumpAll) {
11091                pw.println("-------------------------------------------------------------------------------");
11092            }
11093            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11094            pw.println();
11095            if (dumpAll) {
11096                pw.println("-------------------------------------------------------------------------------");
11097            }
11098            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11099            pw.println();
11100            if (dumpAll) {
11101                pw.println("-------------------------------------------------------------------------------");
11102            }
11103            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11104        }
11105        Binder.restoreCallingIdentity(origId);
11106    }
11107
11108    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11109            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11110        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11111
11112        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11113                dumpPackage);
11114        boolean needSep = printedAnything;
11115
11116        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11117                dumpPackage, needSep, "  mFocusedActivity: ");
11118        if (printed) {
11119            printedAnything = true;
11120            needSep = false;
11121        }
11122
11123        if (dumpPackage == null) {
11124            if (needSep) {
11125                pw.println();
11126            }
11127            needSep = true;
11128            printedAnything = true;
11129            mStackSupervisor.dump(pw, "  ");
11130        }
11131
11132        if (mRecentTasks.size() > 0) {
11133            boolean printedHeader = false;
11134
11135            final int N = mRecentTasks.size();
11136            for (int i=0; i<N; i++) {
11137                TaskRecord tr = mRecentTasks.get(i);
11138                if (dumpPackage != null) {
11139                    if (tr.realActivity == null ||
11140                            !dumpPackage.equals(tr.realActivity)) {
11141                        continue;
11142                    }
11143                }
11144                if (!printedHeader) {
11145                    if (needSep) {
11146                        pw.println();
11147                    }
11148                    pw.println("  Recent tasks:");
11149                    printedHeader = true;
11150                    printedAnything = true;
11151                }
11152                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11153                        pw.println(tr);
11154                if (dumpAll) {
11155                    mRecentTasks.get(i).dump(pw, "    ");
11156                }
11157            }
11158        }
11159
11160        if (!printedAnything) {
11161            pw.println("  (nothing)");
11162        }
11163    }
11164
11165    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11166            int opti, boolean dumpAll, String dumpPackage) {
11167        boolean needSep = false;
11168        boolean printedAnything = false;
11169        int numPers = 0;
11170
11171        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11172
11173        if (dumpAll) {
11174            final int NP = mProcessNames.getMap().size();
11175            for (int ip=0; ip<NP; ip++) {
11176                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11177                final int NA = procs.size();
11178                for (int ia=0; ia<NA; ia++) {
11179                    ProcessRecord r = procs.valueAt(ia);
11180                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11181                        continue;
11182                    }
11183                    if (!needSep) {
11184                        pw.println("  All known processes:");
11185                        needSep = true;
11186                        printedAnything = true;
11187                    }
11188                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11189                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11190                        pw.print(" "); pw.println(r);
11191                    r.dump(pw, "    ");
11192                    if (r.persistent) {
11193                        numPers++;
11194                    }
11195                }
11196            }
11197        }
11198
11199        if (mIsolatedProcesses.size() > 0) {
11200            boolean printed = false;
11201            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11202                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11203                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11204                    continue;
11205                }
11206                if (!printed) {
11207                    if (needSep) {
11208                        pw.println();
11209                    }
11210                    pw.println("  Isolated process list (sorted by uid):");
11211                    printedAnything = true;
11212                    printed = true;
11213                    needSep = true;
11214                }
11215                pw.println(String.format("%sIsolated #%2d: %s",
11216                        "    ", i, r.toString()));
11217            }
11218        }
11219
11220        if (mLruProcesses.size() > 0) {
11221            if (needSep) {
11222                pw.println();
11223            }
11224            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11225                    pw.print(" total, non-act at ");
11226                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11227                    pw.print(", non-svc at ");
11228                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11229                    pw.println("):");
11230            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11231            needSep = true;
11232            printedAnything = true;
11233        }
11234
11235        if (dumpAll || dumpPackage != null) {
11236            synchronized (mPidsSelfLocked) {
11237                boolean printed = false;
11238                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11239                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11240                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11241                        continue;
11242                    }
11243                    if (!printed) {
11244                        if (needSep) pw.println();
11245                        needSep = true;
11246                        pw.println("  PID mappings:");
11247                        printed = true;
11248                        printedAnything = true;
11249                    }
11250                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11251                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11252                }
11253            }
11254        }
11255
11256        if (mForegroundProcesses.size() > 0) {
11257            synchronized (mPidsSelfLocked) {
11258                boolean printed = false;
11259                for (int i=0; i<mForegroundProcesses.size(); i++) {
11260                    ProcessRecord r = mPidsSelfLocked.get(
11261                            mForegroundProcesses.valueAt(i).pid);
11262                    if (dumpPackage != null && (r == null
11263                            || !r.pkgList.containsKey(dumpPackage))) {
11264                        continue;
11265                    }
11266                    if (!printed) {
11267                        if (needSep) pw.println();
11268                        needSep = true;
11269                        pw.println("  Foreground Processes:");
11270                        printed = true;
11271                        printedAnything = true;
11272                    }
11273                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11274                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11275                }
11276            }
11277        }
11278
11279        if (mPersistentStartingProcesses.size() > 0) {
11280            if (needSep) pw.println();
11281            needSep = true;
11282            printedAnything = true;
11283            pw.println("  Persisent processes that are starting:");
11284            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11285                    "Starting Norm", "Restarting PERS", dumpPackage);
11286        }
11287
11288        if (mRemovedProcesses.size() > 0) {
11289            if (needSep) pw.println();
11290            needSep = true;
11291            printedAnything = true;
11292            pw.println("  Processes that are being removed:");
11293            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11294                    "Removed Norm", "Removed PERS", dumpPackage);
11295        }
11296
11297        if (mProcessesOnHold.size() > 0) {
11298            if (needSep) pw.println();
11299            needSep = true;
11300            printedAnything = true;
11301            pw.println("  Processes that are on old until the system is ready:");
11302            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11303                    "OnHold Norm", "OnHold PERS", dumpPackage);
11304        }
11305
11306        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11307
11308        if (mProcessCrashTimes.getMap().size() > 0) {
11309            boolean printed = false;
11310            long now = SystemClock.uptimeMillis();
11311            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11312            final int NP = pmap.size();
11313            for (int ip=0; ip<NP; ip++) {
11314                String pname = pmap.keyAt(ip);
11315                SparseArray<Long> uids = pmap.valueAt(ip);
11316                final int N = uids.size();
11317                for (int i=0; i<N; i++) {
11318                    int puid = uids.keyAt(i);
11319                    ProcessRecord r = mProcessNames.get(pname, puid);
11320                    if (dumpPackage != null && (r == null
11321                            || !r.pkgList.containsKey(dumpPackage))) {
11322                        continue;
11323                    }
11324                    if (!printed) {
11325                        if (needSep) pw.println();
11326                        needSep = true;
11327                        pw.println("  Time since processes crashed:");
11328                        printed = true;
11329                        printedAnything = true;
11330                    }
11331                    pw.print("    Process "); pw.print(pname);
11332                            pw.print(" uid "); pw.print(puid);
11333                            pw.print(": last crashed ");
11334                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11335                            pw.println(" ago");
11336                }
11337            }
11338        }
11339
11340        if (mBadProcesses.getMap().size() > 0) {
11341            boolean printed = false;
11342            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11343            final int NP = pmap.size();
11344            for (int ip=0; ip<NP; ip++) {
11345                String pname = pmap.keyAt(ip);
11346                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11347                final int N = uids.size();
11348                for (int i=0; i<N; i++) {
11349                    int puid = uids.keyAt(i);
11350                    ProcessRecord r = mProcessNames.get(pname, puid);
11351                    if (dumpPackage != null && (r == null
11352                            || !r.pkgList.containsKey(dumpPackage))) {
11353                        continue;
11354                    }
11355                    if (!printed) {
11356                        if (needSep) pw.println();
11357                        needSep = true;
11358                        pw.println("  Bad processes:");
11359                        printedAnything = true;
11360                    }
11361                    BadProcessInfo info = uids.valueAt(i);
11362                    pw.print("    Bad process "); pw.print(pname);
11363                            pw.print(" uid "); pw.print(puid);
11364                            pw.print(": crashed at time "); pw.println(info.time);
11365                    if (info.shortMsg != null) {
11366                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11367                    }
11368                    if (info.longMsg != null) {
11369                        pw.print("      Long msg: "); pw.println(info.longMsg);
11370                    }
11371                    if (info.stack != null) {
11372                        pw.println("      Stack:");
11373                        int lastPos = 0;
11374                        for (int pos=0; pos<info.stack.length(); pos++) {
11375                            if (info.stack.charAt(pos) == '\n') {
11376                                pw.print("        ");
11377                                pw.write(info.stack, lastPos, pos-lastPos);
11378                                pw.println();
11379                                lastPos = pos+1;
11380                            }
11381                        }
11382                        if (lastPos < info.stack.length()) {
11383                            pw.print("        ");
11384                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11385                            pw.println();
11386                        }
11387                    }
11388                }
11389            }
11390        }
11391
11392        if (dumpPackage == null) {
11393            pw.println();
11394            needSep = false;
11395            pw.println("  mStartedUsers:");
11396            for (int i=0; i<mStartedUsers.size(); i++) {
11397                UserStartedState uss = mStartedUsers.valueAt(i);
11398                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11399                        pw.print(": "); uss.dump("", pw);
11400            }
11401            pw.print("  mStartedUserArray: [");
11402            for (int i=0; i<mStartedUserArray.length; i++) {
11403                if (i > 0) pw.print(", ");
11404                pw.print(mStartedUserArray[i]);
11405            }
11406            pw.println("]");
11407            pw.print("  mUserLru: [");
11408            for (int i=0; i<mUserLru.size(); i++) {
11409                if (i > 0) pw.print(", ");
11410                pw.print(mUserLru.get(i));
11411            }
11412            pw.println("]");
11413            if (dumpAll) {
11414                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11415            }
11416        }
11417        if (mHomeProcess != null && (dumpPackage == null
11418                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11419            if (needSep) {
11420                pw.println();
11421                needSep = false;
11422            }
11423            pw.println("  mHomeProcess: " + mHomeProcess);
11424        }
11425        if (mPreviousProcess != null && (dumpPackage == null
11426                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11427            if (needSep) {
11428                pw.println();
11429                needSep = false;
11430            }
11431            pw.println("  mPreviousProcess: " + mPreviousProcess);
11432        }
11433        if (dumpAll) {
11434            StringBuilder sb = new StringBuilder(128);
11435            sb.append("  mPreviousProcessVisibleTime: ");
11436            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11437            pw.println(sb);
11438        }
11439        if (mHeavyWeightProcess != null && (dumpPackage == null
11440                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11441            if (needSep) {
11442                pw.println();
11443                needSep = false;
11444            }
11445            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11446        }
11447        if (dumpPackage == null) {
11448            pw.println("  mConfiguration: " + mConfiguration);
11449        }
11450        if (dumpAll) {
11451            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11452            if (mCompatModePackages.getPackages().size() > 0) {
11453                boolean printed = false;
11454                for (Map.Entry<String, Integer> entry
11455                        : mCompatModePackages.getPackages().entrySet()) {
11456                    String pkg = entry.getKey();
11457                    int mode = entry.getValue();
11458                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11459                        continue;
11460                    }
11461                    if (!printed) {
11462                        pw.println("  mScreenCompatPackages:");
11463                        printed = true;
11464                    }
11465                    pw.print("    "); pw.print(pkg); pw.print(": ");
11466                            pw.print(mode); pw.println();
11467                }
11468            }
11469        }
11470        if (dumpPackage == null) {
11471            if (mSleeping || mWentToSleep || mLockScreenShown) {
11472                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11473                        + " mLockScreenShown " + mLockScreenShown);
11474            }
11475            if (mShuttingDown || mRunningVoice) {
11476                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11477            }
11478        }
11479        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11480                || mOrigWaitForDebugger) {
11481            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11482                    || dumpPackage.equals(mOrigDebugApp)) {
11483                if (needSep) {
11484                    pw.println();
11485                    needSep = false;
11486                }
11487                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11488                        + " mDebugTransient=" + mDebugTransient
11489                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11490            }
11491        }
11492        if (mOpenGlTraceApp != null) {
11493            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11494                if (needSep) {
11495                    pw.println();
11496                    needSep = false;
11497                }
11498                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11499            }
11500        }
11501        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11502                || mProfileFd != null) {
11503            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11504                if (needSep) {
11505                    pw.println();
11506                    needSep = false;
11507                }
11508                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11509                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11510                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11511                        + mAutoStopProfiler);
11512            }
11513        }
11514        if (dumpPackage == null) {
11515            if (mAlwaysFinishActivities || mController != null) {
11516                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11517                        + " mController=" + mController);
11518            }
11519            if (dumpAll) {
11520                pw.println("  Total persistent processes: " + numPers);
11521                pw.println("  mProcessesReady=" + mProcessesReady
11522                        + " mSystemReady=" + mSystemReady);
11523                pw.println("  mBooting=" + mBooting
11524                        + " mBooted=" + mBooted
11525                        + " mFactoryTest=" + mFactoryTest);
11526                pw.print("  mLastPowerCheckRealtime=");
11527                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11528                        pw.println("");
11529                pw.print("  mLastPowerCheckUptime=");
11530                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11531                        pw.println("");
11532                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11533                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11534                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11535                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11536                        + " (" + mLruProcesses.size() + " total)"
11537                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11538                        + " mNumServiceProcs=" + mNumServiceProcs
11539                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11540                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11541                        + " mLastMemoryLevel" + mLastMemoryLevel
11542                        + " mLastNumProcesses" + mLastNumProcesses);
11543                long now = SystemClock.uptimeMillis();
11544                pw.print("  mLastIdleTime=");
11545                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11546                        pw.print(" mLowRamSinceLastIdle=");
11547                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11548                        pw.println();
11549            }
11550        }
11551
11552        if (!printedAnything) {
11553            pw.println("  (nothing)");
11554        }
11555    }
11556
11557    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11558            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11559        if (mProcessesToGc.size() > 0) {
11560            boolean printed = false;
11561            long now = SystemClock.uptimeMillis();
11562            for (int i=0; i<mProcessesToGc.size(); i++) {
11563                ProcessRecord proc = mProcessesToGc.get(i);
11564                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11565                    continue;
11566                }
11567                if (!printed) {
11568                    if (needSep) pw.println();
11569                    needSep = true;
11570                    pw.println("  Processes that are waiting to GC:");
11571                    printed = true;
11572                }
11573                pw.print("    Process "); pw.println(proc);
11574                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11575                        pw.print(", last gced=");
11576                        pw.print(now-proc.lastRequestedGc);
11577                        pw.print(" ms ago, last lowMem=");
11578                        pw.print(now-proc.lastLowMemory);
11579                        pw.println(" ms ago");
11580
11581            }
11582        }
11583        return needSep;
11584    }
11585
11586    void printOomLevel(PrintWriter pw, String name, int adj) {
11587        pw.print("    ");
11588        if (adj >= 0) {
11589            pw.print(' ');
11590            if (adj < 10) pw.print(' ');
11591        } else {
11592            if (adj > -10) pw.print(' ');
11593        }
11594        pw.print(adj);
11595        pw.print(": ");
11596        pw.print(name);
11597        pw.print(" (");
11598        pw.print(mProcessList.getMemLevel(adj)/1024);
11599        pw.println(" kB)");
11600    }
11601
11602    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11603            int opti, boolean dumpAll) {
11604        boolean needSep = false;
11605
11606        if (mLruProcesses.size() > 0) {
11607            if (needSep) pw.println();
11608            needSep = true;
11609            pw.println("  OOM levels:");
11610            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11611            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11612            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11613            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11614            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11615            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11616            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11617            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11618            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11619            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11620            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11621            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11622            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11623
11624            if (needSep) pw.println();
11625            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11626                    pw.print(" total, non-act at ");
11627                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11628                    pw.print(", non-svc at ");
11629                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11630                    pw.println("):");
11631            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11632            needSep = true;
11633        }
11634
11635        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11636
11637        pw.println();
11638        pw.println("  mHomeProcess: " + mHomeProcess);
11639        pw.println("  mPreviousProcess: " + mPreviousProcess);
11640        if (mHeavyWeightProcess != null) {
11641            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11642        }
11643
11644        return true;
11645    }
11646
11647    /**
11648     * There are three ways to call this:
11649     *  - no provider specified: dump all the providers
11650     *  - a flattened component name that matched an existing provider was specified as the
11651     *    first arg: dump that one provider
11652     *  - the first arg isn't the flattened component name of an existing provider:
11653     *    dump all providers whose component contains the first arg as a substring
11654     */
11655    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11656            int opti, boolean dumpAll) {
11657        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11658    }
11659
11660    static class ItemMatcher {
11661        ArrayList<ComponentName> components;
11662        ArrayList<String> strings;
11663        ArrayList<Integer> objects;
11664        boolean all;
11665
11666        ItemMatcher() {
11667            all = true;
11668        }
11669
11670        void build(String name) {
11671            ComponentName componentName = ComponentName.unflattenFromString(name);
11672            if (componentName != null) {
11673                if (components == null) {
11674                    components = new ArrayList<ComponentName>();
11675                }
11676                components.add(componentName);
11677                all = false;
11678            } else {
11679                int objectId = 0;
11680                // Not a '/' separated full component name; maybe an object ID?
11681                try {
11682                    objectId = Integer.parseInt(name, 16);
11683                    if (objects == null) {
11684                        objects = new ArrayList<Integer>();
11685                    }
11686                    objects.add(objectId);
11687                    all = false;
11688                } catch (RuntimeException e) {
11689                    // Not an integer; just do string match.
11690                    if (strings == null) {
11691                        strings = new ArrayList<String>();
11692                    }
11693                    strings.add(name);
11694                    all = false;
11695                }
11696            }
11697        }
11698
11699        int build(String[] args, int opti) {
11700            for (; opti<args.length; opti++) {
11701                String name = args[opti];
11702                if ("--".equals(name)) {
11703                    return opti+1;
11704                }
11705                build(name);
11706            }
11707            return opti;
11708        }
11709
11710        boolean match(Object object, ComponentName comp) {
11711            if (all) {
11712                return true;
11713            }
11714            if (components != null) {
11715                for (int i=0; i<components.size(); i++) {
11716                    if (components.get(i).equals(comp)) {
11717                        return true;
11718                    }
11719                }
11720            }
11721            if (objects != null) {
11722                for (int i=0; i<objects.size(); i++) {
11723                    if (System.identityHashCode(object) == objects.get(i)) {
11724                        return true;
11725                    }
11726                }
11727            }
11728            if (strings != null) {
11729                String flat = comp.flattenToString();
11730                for (int i=0; i<strings.size(); i++) {
11731                    if (flat.contains(strings.get(i))) {
11732                        return true;
11733                    }
11734                }
11735            }
11736            return false;
11737        }
11738    }
11739
11740    /**
11741     * There are three things that cmd can be:
11742     *  - a flattened component name that matches an existing activity
11743     *  - the cmd arg isn't the flattened component name of an existing activity:
11744     *    dump all activity whose component contains the cmd as a substring
11745     *  - A hex number of the ActivityRecord object instance.
11746     */
11747    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11748            int opti, boolean dumpAll) {
11749        ArrayList<ActivityRecord> activities;
11750
11751        synchronized (this) {
11752            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11753        }
11754
11755        if (activities.size() <= 0) {
11756            return false;
11757        }
11758
11759        String[] newArgs = new String[args.length - opti];
11760        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11761
11762        TaskRecord lastTask = null;
11763        boolean needSep = false;
11764        for (int i=activities.size()-1; i>=0; i--) {
11765            ActivityRecord r = activities.get(i);
11766            if (needSep) {
11767                pw.println();
11768            }
11769            needSep = true;
11770            synchronized (this) {
11771                if (lastTask != r.task) {
11772                    lastTask = r.task;
11773                    pw.print("TASK "); pw.print(lastTask.affinity);
11774                            pw.print(" id="); pw.println(lastTask.taskId);
11775                    if (dumpAll) {
11776                        lastTask.dump(pw, "  ");
11777                    }
11778                }
11779            }
11780            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11781        }
11782        return true;
11783    }
11784
11785    /**
11786     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11787     * there is a thread associated with the activity.
11788     */
11789    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11790            final ActivityRecord r, String[] args, boolean dumpAll) {
11791        String innerPrefix = prefix + "  ";
11792        synchronized (this) {
11793            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11794                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11795                    pw.print(" pid=");
11796                    if (r.app != null) pw.println(r.app.pid);
11797                    else pw.println("(not running)");
11798            if (dumpAll) {
11799                r.dump(pw, innerPrefix);
11800            }
11801        }
11802        if (r.app != null && r.app.thread != null) {
11803            // flush anything that is already in the PrintWriter since the thread is going
11804            // to write to the file descriptor directly
11805            pw.flush();
11806            try {
11807                TransferPipe tp = new TransferPipe();
11808                try {
11809                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11810                            r.appToken, innerPrefix, args);
11811                    tp.go(fd);
11812                } finally {
11813                    tp.kill();
11814                }
11815            } catch (IOException e) {
11816                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11817            } catch (RemoteException e) {
11818                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11819            }
11820        }
11821    }
11822
11823    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11824            int opti, boolean dumpAll, String dumpPackage) {
11825        boolean needSep = false;
11826        boolean onlyHistory = false;
11827        boolean printedAnything = false;
11828
11829        if ("history".equals(dumpPackage)) {
11830            if (opti < args.length && "-s".equals(args[opti])) {
11831                dumpAll = false;
11832            }
11833            onlyHistory = true;
11834            dumpPackage = null;
11835        }
11836
11837        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11838        if (!onlyHistory && dumpAll) {
11839            if (mRegisteredReceivers.size() > 0) {
11840                boolean printed = false;
11841                Iterator it = mRegisteredReceivers.values().iterator();
11842                while (it.hasNext()) {
11843                    ReceiverList r = (ReceiverList)it.next();
11844                    if (dumpPackage != null && (r.app == null ||
11845                            !dumpPackage.equals(r.app.info.packageName))) {
11846                        continue;
11847                    }
11848                    if (!printed) {
11849                        pw.println("  Registered Receivers:");
11850                        needSep = true;
11851                        printed = true;
11852                        printedAnything = true;
11853                    }
11854                    pw.print("  * "); pw.println(r);
11855                    r.dump(pw, "    ");
11856                }
11857            }
11858
11859            if (mReceiverResolver.dump(pw, needSep ?
11860                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11861                    "    ", dumpPackage, false)) {
11862                needSep = true;
11863                printedAnything = true;
11864            }
11865        }
11866
11867        for (BroadcastQueue q : mBroadcastQueues) {
11868            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11869            printedAnything |= needSep;
11870        }
11871
11872        needSep = true;
11873
11874        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11875            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11876                if (needSep) {
11877                    pw.println();
11878                }
11879                needSep = true;
11880                printedAnything = true;
11881                pw.print("  Sticky broadcasts for user ");
11882                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11883                StringBuilder sb = new StringBuilder(128);
11884                for (Map.Entry<String, ArrayList<Intent>> ent
11885                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11886                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11887                    if (dumpAll) {
11888                        pw.println(":");
11889                        ArrayList<Intent> intents = ent.getValue();
11890                        final int N = intents.size();
11891                        for (int i=0; i<N; i++) {
11892                            sb.setLength(0);
11893                            sb.append("    Intent: ");
11894                            intents.get(i).toShortString(sb, false, true, false, false);
11895                            pw.println(sb.toString());
11896                            Bundle bundle = intents.get(i).getExtras();
11897                            if (bundle != null) {
11898                                pw.print("      ");
11899                                pw.println(bundle.toString());
11900                            }
11901                        }
11902                    } else {
11903                        pw.println("");
11904                    }
11905                }
11906            }
11907        }
11908
11909        if (!onlyHistory && dumpAll) {
11910            pw.println();
11911            for (BroadcastQueue queue : mBroadcastQueues) {
11912                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11913                        + queue.mBroadcastsScheduled);
11914            }
11915            pw.println("  mHandler:");
11916            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11917            needSep = true;
11918            printedAnything = true;
11919        }
11920
11921        if (!printedAnything) {
11922            pw.println("  (nothing)");
11923        }
11924    }
11925
11926    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11927            int opti, boolean dumpAll, String dumpPackage) {
11928        boolean needSep;
11929        boolean printedAnything = false;
11930
11931        ItemMatcher matcher = new ItemMatcher();
11932        matcher.build(args, opti);
11933
11934        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11935
11936        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11937        printedAnything |= needSep;
11938
11939        if (mLaunchingProviders.size() > 0) {
11940            boolean printed = false;
11941            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11942                ContentProviderRecord r = mLaunchingProviders.get(i);
11943                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11944                    continue;
11945                }
11946                if (!printed) {
11947                    if (needSep) pw.println();
11948                    needSep = true;
11949                    pw.println("  Launching content providers:");
11950                    printed = true;
11951                    printedAnything = true;
11952                }
11953                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11954                        pw.println(r);
11955            }
11956        }
11957
11958        if (mGrantedUriPermissions.size() > 0) {
11959            boolean printed = false;
11960            int dumpUid = -2;
11961            if (dumpPackage != null) {
11962                try {
11963                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11964                } catch (NameNotFoundException e) {
11965                    dumpUid = -1;
11966                }
11967            }
11968            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11969                int uid = mGrantedUriPermissions.keyAt(i);
11970                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11971                    continue;
11972                }
11973                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11974                if (!printed) {
11975                    if (needSep) pw.println();
11976                    needSep = true;
11977                    pw.println("  Granted Uri Permissions:");
11978                    printed = true;
11979                    printedAnything = true;
11980                }
11981                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11982                for (UriPermission perm : perms.values()) {
11983                    pw.print("    "); pw.println(perm);
11984                    if (dumpAll) {
11985                        perm.dump(pw, "      ");
11986                    }
11987                }
11988            }
11989        }
11990
11991        if (!printedAnything) {
11992            pw.println("  (nothing)");
11993        }
11994    }
11995
11996    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11997            int opti, boolean dumpAll, String dumpPackage) {
11998        boolean printed = false;
11999
12000        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12001
12002        if (mIntentSenderRecords.size() > 0) {
12003            Iterator<WeakReference<PendingIntentRecord>> it
12004                    = mIntentSenderRecords.values().iterator();
12005            while (it.hasNext()) {
12006                WeakReference<PendingIntentRecord> ref = it.next();
12007                PendingIntentRecord rec = ref != null ? ref.get(): null;
12008                if (dumpPackage != null && (rec == null
12009                        || !dumpPackage.equals(rec.key.packageName))) {
12010                    continue;
12011                }
12012                printed = true;
12013                if (rec != null) {
12014                    pw.print("  * "); pw.println(rec);
12015                    if (dumpAll) {
12016                        rec.dump(pw, "    ");
12017                    }
12018                } else {
12019                    pw.print("  * "); pw.println(ref);
12020                }
12021            }
12022        }
12023
12024        if (!printed) {
12025            pw.println("  (nothing)");
12026        }
12027    }
12028
12029    private static final int dumpProcessList(PrintWriter pw,
12030            ActivityManagerService service, List list,
12031            String prefix, String normalLabel, String persistentLabel,
12032            String dumpPackage) {
12033        int numPers = 0;
12034        final int N = list.size()-1;
12035        for (int i=N; i>=0; i--) {
12036            ProcessRecord r = (ProcessRecord)list.get(i);
12037            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12038                continue;
12039            }
12040            pw.println(String.format("%s%s #%2d: %s",
12041                    prefix, (r.persistent ? persistentLabel : normalLabel),
12042                    i, r.toString()));
12043            if (r.persistent) {
12044                numPers++;
12045            }
12046        }
12047        return numPers;
12048    }
12049
12050    private static final boolean dumpProcessOomList(PrintWriter pw,
12051            ActivityManagerService service, List<ProcessRecord> origList,
12052            String prefix, String normalLabel, String persistentLabel,
12053            boolean inclDetails, String dumpPackage) {
12054
12055        ArrayList<Pair<ProcessRecord, Integer>> list
12056                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12057        for (int i=0; i<origList.size(); i++) {
12058            ProcessRecord r = origList.get(i);
12059            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12060                continue;
12061            }
12062            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12063        }
12064
12065        if (list.size() <= 0) {
12066            return false;
12067        }
12068
12069        Comparator<Pair<ProcessRecord, Integer>> comparator
12070                = new Comparator<Pair<ProcessRecord, Integer>>() {
12071            @Override
12072            public int compare(Pair<ProcessRecord, Integer> object1,
12073                    Pair<ProcessRecord, Integer> object2) {
12074                if (object1.first.setAdj != object2.first.setAdj) {
12075                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12076                }
12077                if (object1.second.intValue() != object2.second.intValue()) {
12078                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12079                }
12080                return 0;
12081            }
12082        };
12083
12084        Collections.sort(list, comparator);
12085
12086        final long curRealtime = SystemClock.elapsedRealtime();
12087        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12088        final long curUptime = SystemClock.uptimeMillis();
12089        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12090
12091        for (int i=list.size()-1; i>=0; i--) {
12092            ProcessRecord r = list.get(i).first;
12093            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12094            char schedGroup;
12095            switch (r.setSchedGroup) {
12096                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12097                    schedGroup = 'B';
12098                    break;
12099                case Process.THREAD_GROUP_DEFAULT:
12100                    schedGroup = 'F';
12101                    break;
12102                default:
12103                    schedGroup = '?';
12104                    break;
12105            }
12106            char foreground;
12107            if (r.foregroundActivities) {
12108                foreground = 'A';
12109            } else if (r.foregroundServices) {
12110                foreground = 'S';
12111            } else {
12112                foreground = ' ';
12113            }
12114            String procState = ProcessList.makeProcStateString(r.curProcState);
12115            pw.print(prefix);
12116            pw.print(r.persistent ? persistentLabel : normalLabel);
12117            pw.print(" #");
12118            int num = (origList.size()-1)-list.get(i).second;
12119            if (num < 10) pw.print(' ');
12120            pw.print(num);
12121            pw.print(": ");
12122            pw.print(oomAdj);
12123            pw.print(' ');
12124            pw.print(schedGroup);
12125            pw.print('/');
12126            pw.print(foreground);
12127            pw.print('/');
12128            pw.print(procState);
12129            pw.print(" trm:");
12130            if (r.trimMemoryLevel < 10) pw.print(' ');
12131            pw.print(r.trimMemoryLevel);
12132            pw.print(' ');
12133            pw.print(r.toShortString());
12134            pw.print(" (");
12135            pw.print(r.adjType);
12136            pw.println(')');
12137            if (r.adjSource != null || r.adjTarget != null) {
12138                pw.print(prefix);
12139                pw.print("    ");
12140                if (r.adjTarget instanceof ComponentName) {
12141                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12142                } else if (r.adjTarget != null) {
12143                    pw.print(r.adjTarget.toString());
12144                } else {
12145                    pw.print("{null}");
12146                }
12147                pw.print("<=");
12148                if (r.adjSource instanceof ProcessRecord) {
12149                    pw.print("Proc{");
12150                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12151                    pw.println("}");
12152                } else if (r.adjSource != null) {
12153                    pw.println(r.adjSource.toString());
12154                } else {
12155                    pw.println("{null}");
12156                }
12157            }
12158            if (inclDetails) {
12159                pw.print(prefix);
12160                pw.print("    ");
12161                pw.print("oom: max="); pw.print(r.maxAdj);
12162                pw.print(" curRaw="); pw.print(r.curRawAdj);
12163                pw.print(" setRaw="); pw.print(r.setRawAdj);
12164                pw.print(" cur="); pw.print(r.curAdj);
12165                pw.print(" set="); pw.println(r.setAdj);
12166                pw.print(prefix);
12167                pw.print("    ");
12168                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12169                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12170                pw.print(" lastPss="); pw.print(r.lastPss);
12171                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12172                pw.print(prefix);
12173                pw.print("    ");
12174                pw.print("keeping="); pw.print(r.keeping);
12175                pw.print(" cached="); pw.print(r.cached);
12176                pw.print(" empty="); pw.print(r.empty);
12177                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12178
12179                if (!r.keeping) {
12180                    if (r.lastWakeTime != 0) {
12181                        long wtime;
12182                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12183                        synchronized (stats) {
12184                            wtime = stats.getProcessWakeTime(r.info.uid,
12185                                    r.pid, curRealtime);
12186                        }
12187                        long timeUsed = wtime - r.lastWakeTime;
12188                        pw.print(prefix);
12189                        pw.print("    ");
12190                        pw.print("keep awake over ");
12191                        TimeUtils.formatDuration(realtimeSince, pw);
12192                        pw.print(" used ");
12193                        TimeUtils.formatDuration(timeUsed, pw);
12194                        pw.print(" (");
12195                        pw.print((timeUsed*100)/realtimeSince);
12196                        pw.println("%)");
12197                    }
12198                    if (r.lastCpuTime != 0) {
12199                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12200                        pw.print(prefix);
12201                        pw.print("    ");
12202                        pw.print("run cpu over ");
12203                        TimeUtils.formatDuration(uptimeSince, pw);
12204                        pw.print(" used ");
12205                        TimeUtils.formatDuration(timeUsed, pw);
12206                        pw.print(" (");
12207                        pw.print((timeUsed*100)/uptimeSince);
12208                        pw.println("%)");
12209                    }
12210                }
12211            }
12212        }
12213        return true;
12214    }
12215
12216    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12217        ArrayList<ProcessRecord> procs;
12218        synchronized (this) {
12219            if (args != null && args.length > start
12220                    && args[start].charAt(0) != '-') {
12221                procs = new ArrayList<ProcessRecord>();
12222                int pid = -1;
12223                try {
12224                    pid = Integer.parseInt(args[start]);
12225                } catch (NumberFormatException e) {
12226                }
12227                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12228                    ProcessRecord proc = mLruProcesses.get(i);
12229                    if (proc.pid == pid) {
12230                        procs.add(proc);
12231                    } else if (proc.processName.equals(args[start])) {
12232                        procs.add(proc);
12233                    }
12234                }
12235                if (procs.size() <= 0) {
12236                    return null;
12237                }
12238            } else {
12239                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12240            }
12241        }
12242        return procs;
12243    }
12244
12245    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12246            PrintWriter pw, String[] args) {
12247        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12248        if (procs == null) {
12249            pw.println("No process found for: " + args[0]);
12250            return;
12251        }
12252
12253        long uptime = SystemClock.uptimeMillis();
12254        long realtime = SystemClock.elapsedRealtime();
12255        pw.println("Applications Graphics Acceleration Info:");
12256        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12257
12258        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12259            ProcessRecord r = procs.get(i);
12260            if (r.thread != null) {
12261                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12262                pw.flush();
12263                try {
12264                    TransferPipe tp = new TransferPipe();
12265                    try {
12266                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12267                        tp.go(fd);
12268                    } finally {
12269                        tp.kill();
12270                    }
12271                } catch (IOException e) {
12272                    pw.println("Failure while dumping the app: " + r);
12273                    pw.flush();
12274                } catch (RemoteException e) {
12275                    pw.println("Got a RemoteException while dumping the app " + r);
12276                    pw.flush();
12277                }
12278            }
12279        }
12280    }
12281
12282    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12283        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12284        if (procs == null) {
12285            pw.println("No process found for: " + args[0]);
12286            return;
12287        }
12288
12289        pw.println("Applications Database Info:");
12290
12291        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12292            ProcessRecord r = procs.get(i);
12293            if (r.thread != null) {
12294                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12295                pw.flush();
12296                try {
12297                    TransferPipe tp = new TransferPipe();
12298                    try {
12299                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12300                        tp.go(fd);
12301                    } finally {
12302                        tp.kill();
12303                    }
12304                } catch (IOException e) {
12305                    pw.println("Failure while dumping the app: " + r);
12306                    pw.flush();
12307                } catch (RemoteException e) {
12308                    pw.println("Got a RemoteException while dumping the app " + r);
12309                    pw.flush();
12310                }
12311            }
12312        }
12313    }
12314
12315    final static class MemItem {
12316        final boolean isProc;
12317        final String label;
12318        final String shortLabel;
12319        final long pss;
12320        final int id;
12321        final boolean hasActivities;
12322        ArrayList<MemItem> subitems;
12323
12324        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12325                boolean _hasActivities) {
12326            isProc = true;
12327            label = _label;
12328            shortLabel = _shortLabel;
12329            pss = _pss;
12330            id = _id;
12331            hasActivities = _hasActivities;
12332        }
12333
12334        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12335            isProc = false;
12336            label = _label;
12337            shortLabel = _shortLabel;
12338            pss = _pss;
12339            id = _id;
12340            hasActivities = false;
12341        }
12342    }
12343
12344    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12345            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12346        if (sort && !isCompact) {
12347            Collections.sort(items, new Comparator<MemItem>() {
12348                @Override
12349                public int compare(MemItem lhs, MemItem rhs) {
12350                    if (lhs.pss < rhs.pss) {
12351                        return 1;
12352                    } else if (lhs.pss > rhs.pss) {
12353                        return -1;
12354                    }
12355                    return 0;
12356                }
12357            });
12358        }
12359
12360        for (int i=0; i<items.size(); i++) {
12361            MemItem mi = items.get(i);
12362            if (!isCompact) {
12363                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12364            } else if (mi.isProc) {
12365                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12366                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12367                pw.println(mi.hasActivities ? ",a" : ",e");
12368            } else {
12369                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12370                pw.println(mi.pss);
12371            }
12372            if (mi.subitems != null) {
12373                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12374                        true, isCompact);
12375            }
12376        }
12377    }
12378
12379    // These are in KB.
12380    static final long[] DUMP_MEM_BUCKETS = new long[] {
12381        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12382        120*1024, 160*1024, 200*1024,
12383        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12384        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12385    };
12386
12387    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12388            boolean stackLike) {
12389        int start = label.lastIndexOf('.');
12390        if (start >= 0) start++;
12391        else start = 0;
12392        int end = label.length();
12393        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12394            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12395                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12396                out.append(bucket);
12397                out.append(stackLike ? "MB." : "MB ");
12398                out.append(label, start, end);
12399                return;
12400            }
12401        }
12402        out.append(memKB/1024);
12403        out.append(stackLike ? "MB." : "MB ");
12404        out.append(label, start, end);
12405    }
12406
12407    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12408            ProcessList.NATIVE_ADJ,
12409            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12410            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12411            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12412            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12413            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12414    };
12415    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12416            "Native",
12417            "System", "Persistent", "Foreground",
12418            "Visible", "Perceptible",
12419            "Heavy Weight", "Backup",
12420            "A Services", "Home",
12421            "Previous", "B Services", "Cached"
12422    };
12423    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12424            "native",
12425            "sys", "pers", "fore",
12426            "vis", "percept",
12427            "heavy", "backup",
12428            "servicea", "home",
12429            "prev", "serviceb", "cached"
12430    };
12431
12432    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12433            long realtime, boolean isCheckinRequest, boolean isCompact) {
12434        if (isCheckinRequest || isCompact) {
12435            // short checkin version
12436            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12437        } else {
12438            pw.println("Applications Memory Usage (kB):");
12439            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12440        }
12441    }
12442
12443    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12444            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12445        boolean dumpDetails = false;
12446        boolean dumpFullDetails = false;
12447        boolean dumpDalvik = false;
12448        boolean oomOnly = false;
12449        boolean isCompact = false;
12450        boolean localOnly = false;
12451
12452        int opti = 0;
12453        while (opti < args.length) {
12454            String opt = args[opti];
12455            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12456                break;
12457            }
12458            opti++;
12459            if ("-a".equals(opt)) {
12460                dumpDetails = true;
12461                dumpFullDetails = true;
12462                dumpDalvik = true;
12463            } else if ("-d".equals(opt)) {
12464                dumpDalvik = true;
12465            } else if ("-c".equals(opt)) {
12466                isCompact = true;
12467            } else if ("--oom".equals(opt)) {
12468                oomOnly = true;
12469            } else if ("--local".equals(opt)) {
12470                localOnly = true;
12471            } else if ("-h".equals(opt)) {
12472                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12473                pw.println("  -a: include all available information for each process.");
12474                pw.println("  -d: include dalvik details when dumping process details.");
12475                pw.println("  -c: dump in a compact machine-parseable representation.");
12476                pw.println("  --oom: only show processes organized by oom adj.");
12477                pw.println("  --local: only collect details locally, don't call process.");
12478                pw.println("If [process] is specified it can be the name or ");
12479                pw.println("pid of a specific process to dump.");
12480                return;
12481            } else {
12482                pw.println("Unknown argument: " + opt + "; use -h for help");
12483            }
12484        }
12485
12486        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12487        long uptime = SystemClock.uptimeMillis();
12488        long realtime = SystemClock.elapsedRealtime();
12489        final long[] tmpLong = new long[1];
12490
12491        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12492        if (procs == null) {
12493            // No Java processes.  Maybe they want to print a native process.
12494            if (args != null && args.length > opti
12495                    && args[opti].charAt(0) != '-') {
12496                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12497                        = new ArrayList<ProcessCpuTracker.Stats>();
12498                updateCpuStatsNow();
12499                int findPid = -1;
12500                try {
12501                    findPid = Integer.parseInt(args[opti]);
12502                } catch (NumberFormatException e) {
12503                }
12504                synchronized (mProcessCpuThread) {
12505                    final int N = mProcessCpuTracker.countStats();
12506                    for (int i=0; i<N; i++) {
12507                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12508                        if (st.pid == findPid || (st.baseName != null
12509                                && st.baseName.equals(args[opti]))) {
12510                            nativeProcs.add(st);
12511                        }
12512                    }
12513                }
12514                if (nativeProcs.size() > 0) {
12515                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12516                            isCompact);
12517                    Debug.MemoryInfo mi = null;
12518                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12519                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12520                        final int pid = r.pid;
12521                        if (!isCheckinRequest && dumpDetails) {
12522                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12523                        }
12524                        if (mi == null) {
12525                            mi = new Debug.MemoryInfo();
12526                        }
12527                        if (dumpDetails || (!brief && !oomOnly)) {
12528                            Debug.getMemoryInfo(pid, mi);
12529                        } else {
12530                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12531                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12532                        }
12533                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12534                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12535                        if (isCheckinRequest) {
12536                            pw.println();
12537                        }
12538                    }
12539                    return;
12540                }
12541            }
12542            pw.println("No process found for: " + args[opti]);
12543            return;
12544        }
12545
12546        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12547            dumpDetails = true;
12548        }
12549
12550        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12551
12552        String[] innerArgs = new String[args.length-opti];
12553        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12554
12555        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12556        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12557        long nativePss=0, dalvikPss=0, otherPss=0;
12558        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12559
12560        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12561        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12562                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12563
12564        long totalPss = 0;
12565        long cachedPss = 0;
12566
12567        Debug.MemoryInfo mi = null;
12568        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12569            final ProcessRecord r = procs.get(i);
12570            final IApplicationThread thread;
12571            final int pid;
12572            final int oomAdj;
12573            final boolean hasActivities;
12574            synchronized (this) {
12575                thread = r.thread;
12576                pid = r.pid;
12577                oomAdj = r.getSetAdjWithServices();
12578                hasActivities = r.activities.size() > 0;
12579            }
12580            if (thread != null) {
12581                if (!isCheckinRequest && dumpDetails) {
12582                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12583                }
12584                if (mi == null) {
12585                    mi = new Debug.MemoryInfo();
12586                }
12587                if (dumpDetails || (!brief && !oomOnly)) {
12588                    Debug.getMemoryInfo(pid, mi);
12589                } else {
12590                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12591                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12592                }
12593                if (dumpDetails) {
12594                    if (localOnly) {
12595                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12596                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12597                        if (isCheckinRequest) {
12598                            pw.println();
12599                        }
12600                    } else {
12601                        try {
12602                            pw.flush();
12603                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12604                                    dumpDalvik, innerArgs);
12605                        } catch (RemoteException e) {
12606                            if (!isCheckinRequest) {
12607                                pw.println("Got RemoteException!");
12608                                pw.flush();
12609                            }
12610                        }
12611                    }
12612                }
12613
12614                final long myTotalPss = mi.getTotalPss();
12615                final long myTotalUss = mi.getTotalUss();
12616
12617                synchronized (this) {
12618                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12619                        // Record this for posterity if the process has been stable.
12620                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12621                    }
12622                }
12623
12624                if (!isCheckinRequest && mi != null) {
12625                    totalPss += myTotalPss;
12626                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12627                            (hasActivities ? " / activities)" : ")"),
12628                            r.processName, myTotalPss, pid, hasActivities);
12629                    procMems.add(pssItem);
12630                    procMemsMap.put(pid, pssItem);
12631
12632                    nativePss += mi.nativePss;
12633                    dalvikPss += mi.dalvikPss;
12634                    otherPss += mi.otherPss;
12635                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12636                        long mem = mi.getOtherPss(j);
12637                        miscPss[j] += mem;
12638                        otherPss -= mem;
12639                    }
12640
12641                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12642                        cachedPss += myTotalPss;
12643                    }
12644
12645                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12646                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12647                                || oomIndex == (oomPss.length-1)) {
12648                            oomPss[oomIndex] += myTotalPss;
12649                            if (oomProcs[oomIndex] == null) {
12650                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12651                            }
12652                            oomProcs[oomIndex].add(pssItem);
12653                            break;
12654                        }
12655                    }
12656                }
12657            }
12658        }
12659
12660        if (!isCheckinRequest && procs.size() > 1) {
12661            // If we are showing aggregations, also look for native processes to
12662            // include so that our aggregations are more accurate.
12663            updateCpuStatsNow();
12664            synchronized (mProcessCpuThread) {
12665                final int N = mProcessCpuTracker.countStats();
12666                for (int i=0; i<N; i++) {
12667                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12668                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12669                        if (mi == null) {
12670                            mi = new Debug.MemoryInfo();
12671                        }
12672                        if (!brief && !oomOnly) {
12673                            Debug.getMemoryInfo(st.pid, mi);
12674                        } else {
12675                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12676                            mi.nativePrivateDirty = (int)tmpLong[0];
12677                        }
12678
12679                        final long myTotalPss = mi.getTotalPss();
12680                        totalPss += myTotalPss;
12681
12682                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12683                                st.name, myTotalPss, st.pid, false);
12684                        procMems.add(pssItem);
12685
12686                        nativePss += mi.nativePss;
12687                        dalvikPss += mi.dalvikPss;
12688                        otherPss += mi.otherPss;
12689                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12690                            long mem = mi.getOtherPss(j);
12691                            miscPss[j] += mem;
12692                            otherPss -= mem;
12693                        }
12694                        oomPss[0] += myTotalPss;
12695                        if (oomProcs[0] == null) {
12696                            oomProcs[0] = new ArrayList<MemItem>();
12697                        }
12698                        oomProcs[0].add(pssItem);
12699                    }
12700                }
12701            }
12702
12703            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12704
12705            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12706            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12707            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12708            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12709                String label = Debug.MemoryInfo.getOtherLabel(j);
12710                catMems.add(new MemItem(label, label, miscPss[j], j));
12711            }
12712
12713            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12714            for (int j=0; j<oomPss.length; j++) {
12715                if (oomPss[j] != 0) {
12716                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12717                            : DUMP_MEM_OOM_LABEL[j];
12718                    MemItem item = new MemItem(label, label, oomPss[j],
12719                            DUMP_MEM_OOM_ADJ[j]);
12720                    item.subitems = oomProcs[j];
12721                    oomMems.add(item);
12722                }
12723            }
12724
12725            if (!brief && !oomOnly && !isCompact) {
12726                pw.println();
12727                pw.println("Total PSS by process:");
12728                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12729                pw.println();
12730            }
12731            if (!isCompact) {
12732                pw.println("Total PSS by OOM adjustment:");
12733            }
12734            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12735            if (!brief && !oomOnly) {
12736                PrintWriter out = categoryPw != null ? categoryPw : pw;
12737                if (!isCompact) {
12738                    out.println();
12739                    out.println("Total PSS by category:");
12740                }
12741                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12742            }
12743            if (!isCompact) {
12744                pw.println();
12745            }
12746            MemInfoReader memInfo = new MemInfoReader();
12747            memInfo.readMemInfo();
12748            if (!brief) {
12749                if (!isCompact) {
12750                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12751                    pw.print(" kB (status ");
12752                    switch (mLastMemoryLevel) {
12753                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12754                            pw.println("normal)");
12755                            break;
12756                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12757                            pw.println("moderate)");
12758                            break;
12759                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12760                            pw.println("low)");
12761                            break;
12762                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12763                            pw.println("critical)");
12764                            break;
12765                        default:
12766                            pw.print(mLastMemoryLevel);
12767                            pw.println(")");
12768                            break;
12769                    }
12770                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12771                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12772                            pw.print(cachedPss); pw.print(" cached pss + ");
12773                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12774                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12775                } else {
12776                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12777                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12778                            + memInfo.getFreeSizeKb()); pw.print(",");
12779                    pw.println(totalPss - cachedPss);
12780                }
12781            }
12782            if (!isCompact) {
12783                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12784                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12785                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12786                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12787                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12788                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12789                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12790                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12791                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12792                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12793                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12794            }
12795            if (!brief) {
12796                if (memInfo.getZramTotalSizeKb() != 0) {
12797                    if (!isCompact) {
12798                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12799                                pw.print(" kB physical used for ");
12800                                pw.print(memInfo.getSwapTotalSizeKb()
12801                                        - memInfo.getSwapFreeSizeKb());
12802                                pw.print(" kB in swap (");
12803                                pw.print(memInfo.getSwapTotalSizeKb());
12804                                pw.println(" kB total swap)");
12805                    } else {
12806                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12807                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12808                                pw.println(memInfo.getSwapFreeSizeKb());
12809                    }
12810                }
12811                final int[] SINGLE_LONG_FORMAT = new int[] {
12812                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12813                };
12814                long[] longOut = new long[1];
12815                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12816                        SINGLE_LONG_FORMAT, null, longOut, null);
12817                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12818                longOut[0] = 0;
12819                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12820                        SINGLE_LONG_FORMAT, null, longOut, null);
12821                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12822                longOut[0] = 0;
12823                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12824                        SINGLE_LONG_FORMAT, null, longOut, null);
12825                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12826                longOut[0] = 0;
12827                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12828                        SINGLE_LONG_FORMAT, null, longOut, null);
12829                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12830                if (!isCompact) {
12831                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12832                        pw.print("      KSM: "); pw.print(sharing);
12833                                pw.print(" kB saved from shared ");
12834                                pw.print(shared); pw.println(" kB");
12835                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12836                                pw.print(voltile); pw.println(" kB volatile");
12837                    }
12838                    pw.print("   Tuning: ");
12839                    pw.print(ActivityManager.staticGetMemoryClass());
12840                    pw.print(" (large ");
12841                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12842                    pw.print("), oom ");
12843                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12844                    pw.print(" kB");
12845                    pw.print(", restore limit ");
12846                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12847                    pw.print(" kB");
12848                    if (ActivityManager.isLowRamDeviceStatic()) {
12849                        pw.print(" (low-ram)");
12850                    }
12851                    if (ActivityManager.isHighEndGfx()) {
12852                        pw.print(" (high-end-gfx)");
12853                    }
12854                    pw.println();
12855                } else {
12856                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12857                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12858                    pw.println(voltile);
12859                    pw.print("tuning,");
12860                    pw.print(ActivityManager.staticGetMemoryClass());
12861                    pw.print(',');
12862                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12863                    pw.print(',');
12864                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12865                    if (ActivityManager.isLowRamDeviceStatic()) {
12866                        pw.print(",low-ram");
12867                    }
12868                    if (ActivityManager.isHighEndGfx()) {
12869                        pw.print(",high-end-gfx");
12870                    }
12871                    pw.println();
12872                }
12873            }
12874        }
12875    }
12876
12877    /**
12878     * Searches array of arguments for the specified string
12879     * @param args array of argument strings
12880     * @param value value to search for
12881     * @return true if the value is contained in the array
12882     */
12883    private static boolean scanArgs(String[] args, String value) {
12884        if (args != null) {
12885            for (String arg : args) {
12886                if (value.equals(arg)) {
12887                    return true;
12888                }
12889            }
12890        }
12891        return false;
12892    }
12893
12894    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12895            ContentProviderRecord cpr, boolean always) {
12896        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12897
12898        if (!inLaunching || always) {
12899            synchronized (cpr) {
12900                cpr.launchingApp = null;
12901                cpr.notifyAll();
12902            }
12903            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12904            String names[] = cpr.info.authority.split(";");
12905            for (int j = 0; j < names.length; j++) {
12906                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12907            }
12908        }
12909
12910        for (int i=0; i<cpr.connections.size(); i++) {
12911            ContentProviderConnection conn = cpr.connections.get(i);
12912            if (conn.waiting) {
12913                // If this connection is waiting for the provider, then we don't
12914                // need to mess with its process unless we are always removing
12915                // or for some reason the provider is not currently launching.
12916                if (inLaunching && !always) {
12917                    continue;
12918                }
12919            }
12920            ProcessRecord capp = conn.client;
12921            conn.dead = true;
12922            if (conn.stableCount > 0) {
12923                if (!capp.persistent && capp.thread != null
12924                        && capp.pid != 0
12925                        && capp.pid != MY_PID) {
12926                    killUnneededProcessLocked(capp, "depends on provider "
12927                            + cpr.name.flattenToShortString()
12928                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12929                }
12930            } else if (capp.thread != null && conn.provider.provider != null) {
12931                try {
12932                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12933                } catch (RemoteException e) {
12934                }
12935                // In the protocol here, we don't expect the client to correctly
12936                // clean up this connection, we'll just remove it.
12937                cpr.connections.remove(i);
12938                conn.client.conProviders.remove(conn);
12939            }
12940        }
12941
12942        if (inLaunching && always) {
12943            mLaunchingProviders.remove(cpr);
12944        }
12945        return inLaunching;
12946    }
12947
12948    /**
12949     * Main code for cleaning up a process when it has gone away.  This is
12950     * called both as a result of the process dying, or directly when stopping
12951     * a process when running in single process mode.
12952     */
12953    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12954            boolean restarting, boolean allowRestart, int index) {
12955        if (index >= 0) {
12956            removeLruProcessLocked(app);
12957            ProcessList.remove(app.pid);
12958        }
12959
12960        mProcessesToGc.remove(app);
12961        mPendingPssProcesses.remove(app);
12962
12963        // Dismiss any open dialogs.
12964        if (app.crashDialog != null && !app.forceCrashReport) {
12965            app.crashDialog.dismiss();
12966            app.crashDialog = null;
12967        }
12968        if (app.anrDialog != null) {
12969            app.anrDialog.dismiss();
12970            app.anrDialog = null;
12971        }
12972        if (app.waitDialog != null) {
12973            app.waitDialog.dismiss();
12974            app.waitDialog = null;
12975        }
12976
12977        app.crashing = false;
12978        app.notResponding = false;
12979
12980        app.resetPackageList(mProcessStats);
12981        app.unlinkDeathRecipient();
12982        app.makeInactive(mProcessStats);
12983        app.forcingToForeground = null;
12984        updateProcessForegroundLocked(app, false, false);
12985        app.foregroundActivities = false;
12986        app.hasShownUi = false;
12987        app.treatLikeActivity = false;
12988        app.hasAboveClient = false;
12989        app.hasClientActivities = false;
12990
12991        mServices.killServicesLocked(app, allowRestart);
12992
12993        boolean restart = false;
12994
12995        // Remove published content providers.
12996        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12997            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12998            final boolean always = app.bad || !allowRestart;
12999            if (removeDyingProviderLocked(app, cpr, always) || always) {
13000                // We left the provider in the launching list, need to
13001                // restart it.
13002                restart = true;
13003            }
13004
13005            cpr.provider = null;
13006            cpr.proc = null;
13007        }
13008        app.pubProviders.clear();
13009
13010        // Take care of any launching providers waiting for this process.
13011        if (checkAppInLaunchingProvidersLocked(app, false)) {
13012            restart = true;
13013        }
13014
13015        // Unregister from connected content providers.
13016        if (!app.conProviders.isEmpty()) {
13017            for (int i=0; i<app.conProviders.size(); i++) {
13018                ContentProviderConnection conn = app.conProviders.get(i);
13019                conn.provider.connections.remove(conn);
13020            }
13021            app.conProviders.clear();
13022        }
13023
13024        // At this point there may be remaining entries in mLaunchingProviders
13025        // where we were the only one waiting, so they are no longer of use.
13026        // Look for these and clean up if found.
13027        // XXX Commented out for now.  Trying to figure out a way to reproduce
13028        // the actual situation to identify what is actually going on.
13029        if (false) {
13030            for (int i=0; i<mLaunchingProviders.size(); i++) {
13031                ContentProviderRecord cpr = (ContentProviderRecord)
13032                        mLaunchingProviders.get(i);
13033                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13034                    synchronized (cpr) {
13035                        cpr.launchingApp = null;
13036                        cpr.notifyAll();
13037                    }
13038                }
13039            }
13040        }
13041
13042        skipCurrentReceiverLocked(app);
13043
13044        // Unregister any receivers.
13045        for (int i=app.receivers.size()-1; i>=0; i--) {
13046            removeReceiverLocked(app.receivers.valueAt(i));
13047        }
13048        app.receivers.clear();
13049
13050        // If the app is undergoing backup, tell the backup manager about it
13051        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13052            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13053                    + mBackupTarget.appInfo + " died during backup");
13054            try {
13055                IBackupManager bm = IBackupManager.Stub.asInterface(
13056                        ServiceManager.getService(Context.BACKUP_SERVICE));
13057                bm.agentDisconnected(app.info.packageName);
13058            } catch (RemoteException e) {
13059                // can't happen; backup manager is local
13060            }
13061        }
13062
13063        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13064            ProcessChangeItem item = mPendingProcessChanges.get(i);
13065            if (item.pid == app.pid) {
13066                mPendingProcessChanges.remove(i);
13067                mAvailProcessChanges.add(item);
13068            }
13069        }
13070        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13071
13072        // If the caller is restarting this app, then leave it in its
13073        // current lists and let the caller take care of it.
13074        if (restarting) {
13075            return;
13076        }
13077
13078        if (!app.persistent || app.isolated) {
13079            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13080                    "Removing non-persistent process during cleanup: " + app);
13081            mProcessNames.remove(app.processName, app.uid);
13082            mIsolatedProcesses.remove(app.uid);
13083            if (mHeavyWeightProcess == app) {
13084                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13085                        mHeavyWeightProcess.userId, 0));
13086                mHeavyWeightProcess = null;
13087            }
13088        } else if (!app.removed) {
13089            // This app is persistent, so we need to keep its record around.
13090            // If it is not already on the pending app list, add it there
13091            // and start a new process for it.
13092            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13093                mPersistentStartingProcesses.add(app);
13094                restart = true;
13095            }
13096        }
13097        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13098                "Clean-up removing on hold: " + app);
13099        mProcessesOnHold.remove(app);
13100
13101        if (app == mHomeProcess) {
13102            mHomeProcess = null;
13103        }
13104        if (app == mPreviousProcess) {
13105            mPreviousProcess = null;
13106        }
13107
13108        if (restart && !app.isolated) {
13109            // We have components that still need to be running in the
13110            // process, so re-launch it.
13111            mProcessNames.put(app.processName, app.uid, app);
13112            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13113        } else if (app.pid > 0 && app.pid != MY_PID) {
13114            // Goodbye!
13115            boolean removed;
13116            synchronized (mPidsSelfLocked) {
13117                mPidsSelfLocked.remove(app.pid);
13118                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13119            }
13120            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13121                    app.processName, app.info.uid);
13122            if (app.isolated) {
13123                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13124            }
13125            app.setPid(0);
13126        }
13127    }
13128
13129    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13130        // Look through the content providers we are waiting to have launched,
13131        // and if any run in this process then either schedule a restart of
13132        // the process or kill the client waiting for it if this process has
13133        // gone bad.
13134        int NL = mLaunchingProviders.size();
13135        boolean restart = false;
13136        for (int i=0; i<NL; i++) {
13137            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13138            if (cpr.launchingApp == app) {
13139                if (!alwaysBad && !app.bad) {
13140                    restart = true;
13141                } else {
13142                    removeDyingProviderLocked(app, cpr, true);
13143                    // cpr should have been removed from mLaunchingProviders
13144                    NL = mLaunchingProviders.size();
13145                    i--;
13146                }
13147            }
13148        }
13149        return restart;
13150    }
13151
13152    // =========================================================
13153    // SERVICES
13154    // =========================================================
13155
13156    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13157            int flags) {
13158        enforceNotIsolatedCaller("getServices");
13159        synchronized (this) {
13160            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13161        }
13162    }
13163
13164    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13165        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13166        synchronized (this) {
13167            return mServices.getRunningServiceControlPanelLocked(name);
13168        }
13169    }
13170
13171    public ComponentName startService(IApplicationThread caller, Intent service,
13172            String resolvedType, int userId) {
13173        enforceNotIsolatedCaller("startService");
13174        // Refuse possible leaked file descriptors
13175        if (service != null && service.hasFileDescriptors() == true) {
13176            throw new IllegalArgumentException("File descriptors passed in Intent");
13177        }
13178
13179        if (DEBUG_SERVICE)
13180            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13181        synchronized(this) {
13182            final int callingPid = Binder.getCallingPid();
13183            final int callingUid = Binder.getCallingUid();
13184            final long origId = Binder.clearCallingIdentity();
13185            ComponentName res = mServices.startServiceLocked(caller, service,
13186                    resolvedType, callingPid, callingUid, userId);
13187            Binder.restoreCallingIdentity(origId);
13188            return res;
13189        }
13190    }
13191
13192    ComponentName startServiceInPackage(int uid,
13193            Intent service, String resolvedType, int userId) {
13194        synchronized(this) {
13195            if (DEBUG_SERVICE)
13196                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13197            final long origId = Binder.clearCallingIdentity();
13198            ComponentName res = mServices.startServiceLocked(null, service,
13199                    resolvedType, -1, uid, userId);
13200            Binder.restoreCallingIdentity(origId);
13201            return res;
13202        }
13203    }
13204
13205    public int stopService(IApplicationThread caller, Intent service,
13206            String resolvedType, int userId) {
13207        enforceNotIsolatedCaller("stopService");
13208        // Refuse possible leaked file descriptors
13209        if (service != null && service.hasFileDescriptors() == true) {
13210            throw new IllegalArgumentException("File descriptors passed in Intent");
13211        }
13212
13213        synchronized(this) {
13214            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13215        }
13216    }
13217
13218    public IBinder peekService(Intent service, String resolvedType) {
13219        enforceNotIsolatedCaller("peekService");
13220        // Refuse possible leaked file descriptors
13221        if (service != null && service.hasFileDescriptors() == true) {
13222            throw new IllegalArgumentException("File descriptors passed in Intent");
13223        }
13224        synchronized(this) {
13225            return mServices.peekServiceLocked(service, resolvedType);
13226        }
13227    }
13228
13229    public boolean stopServiceToken(ComponentName className, IBinder token,
13230            int startId) {
13231        synchronized(this) {
13232            return mServices.stopServiceTokenLocked(className, token, startId);
13233        }
13234    }
13235
13236    public void setServiceForeground(ComponentName className, IBinder token,
13237            int id, Notification notification, boolean removeNotification) {
13238        synchronized(this) {
13239            mServices.setServiceForegroundLocked(className, token, id, notification,
13240                    removeNotification);
13241        }
13242    }
13243
13244    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13245            boolean requireFull, String name, String callerPackage) {
13246        final int callingUserId = UserHandle.getUserId(callingUid);
13247        if (callingUserId != userId) {
13248            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13249                if ((requireFull || checkComponentPermission(
13250                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13251                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13252                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13253                                callingPid, callingUid, -1, true)
13254                                != PackageManager.PERMISSION_GRANTED) {
13255                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13256                        // In this case, they would like to just execute as their
13257                        // owner user instead of failing.
13258                        userId = callingUserId;
13259                    } else {
13260                        StringBuilder builder = new StringBuilder(128);
13261                        builder.append("Permission Denial: ");
13262                        builder.append(name);
13263                        if (callerPackage != null) {
13264                            builder.append(" from ");
13265                            builder.append(callerPackage);
13266                        }
13267                        builder.append(" asks to run as user ");
13268                        builder.append(userId);
13269                        builder.append(" but is calling from user ");
13270                        builder.append(UserHandle.getUserId(callingUid));
13271                        builder.append("; this requires ");
13272                        builder.append(INTERACT_ACROSS_USERS_FULL);
13273                        if (!requireFull) {
13274                            builder.append(" or ");
13275                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13276                        }
13277                        String msg = builder.toString();
13278                        Slog.w(TAG, msg);
13279                        throw new SecurityException(msg);
13280                    }
13281                }
13282            }
13283            if (userId == UserHandle.USER_CURRENT
13284                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13285                // Note that we may be accessing this outside of a lock...
13286                // shouldn't be a big deal, if this is being called outside
13287                // of a locked context there is intrinsically a race with
13288                // the value the caller will receive and someone else changing it.
13289                userId = mCurrentUserId;
13290            }
13291            if (!allowAll && userId < 0) {
13292                throw new IllegalArgumentException(
13293                        "Call does not support special user #" + userId);
13294            }
13295        }
13296        return userId;
13297    }
13298
13299    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13300            String className, int flags) {
13301        boolean result = false;
13302        // For apps that don't have pre-defined UIDs, check for permission
13303        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13304            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13305                if (ActivityManager.checkUidPermission(
13306                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13307                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13308                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13309                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13310                            + " requests FLAG_SINGLE_USER, but app does not hold "
13311                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13312                    Slog.w(TAG, msg);
13313                    throw new SecurityException(msg);
13314                }
13315                // Permission passed
13316                result = true;
13317            }
13318        } else if ("system".equals(componentProcessName)) {
13319            result = true;
13320        } else {
13321            // App with pre-defined UID, check if it's a persistent app
13322            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13323        }
13324        if (DEBUG_MU) {
13325            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13326                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13327        }
13328        return result;
13329    }
13330
13331    /**
13332     * Checks to see if the caller is in the same app as the singleton
13333     * component, or the component is in a special app. It allows special apps
13334     * to export singleton components but prevents exporting singleton
13335     * components for regular apps.
13336     */
13337    boolean isValidSingletonCall(int callingUid, int componentUid) {
13338        int componentAppId = UserHandle.getAppId(componentUid);
13339        return UserHandle.isSameApp(callingUid, componentUid)
13340                || componentAppId == Process.SYSTEM_UID
13341                || componentAppId == Process.PHONE_UID
13342                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13343                        == PackageManager.PERMISSION_GRANTED;
13344    }
13345
13346    public int bindService(IApplicationThread caller, IBinder token,
13347            Intent service, String resolvedType,
13348            IServiceConnection connection, int flags, int userId) {
13349        enforceNotIsolatedCaller("bindService");
13350        // Refuse possible leaked file descriptors
13351        if (service != null && service.hasFileDescriptors() == true) {
13352            throw new IllegalArgumentException("File descriptors passed in Intent");
13353        }
13354
13355        synchronized(this) {
13356            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13357                    connection, flags, userId);
13358        }
13359    }
13360
13361    public boolean unbindService(IServiceConnection connection) {
13362        synchronized (this) {
13363            return mServices.unbindServiceLocked(connection);
13364        }
13365    }
13366
13367    public void publishService(IBinder token, Intent intent, IBinder service) {
13368        // Refuse possible leaked file descriptors
13369        if (intent != null && intent.hasFileDescriptors() == true) {
13370            throw new IllegalArgumentException("File descriptors passed in Intent");
13371        }
13372
13373        synchronized(this) {
13374            if (!(token instanceof ServiceRecord)) {
13375                throw new IllegalArgumentException("Invalid service token");
13376            }
13377            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13378        }
13379    }
13380
13381    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13382        // Refuse possible leaked file descriptors
13383        if (intent != null && intent.hasFileDescriptors() == true) {
13384            throw new IllegalArgumentException("File descriptors passed in Intent");
13385        }
13386
13387        synchronized(this) {
13388            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13389        }
13390    }
13391
13392    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13393        synchronized(this) {
13394            if (!(token instanceof ServiceRecord)) {
13395                throw new IllegalArgumentException("Invalid service token");
13396            }
13397            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13398        }
13399    }
13400
13401    // =========================================================
13402    // BACKUP AND RESTORE
13403    // =========================================================
13404
13405    // Cause the target app to be launched if necessary and its backup agent
13406    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13407    // activity manager to announce its creation.
13408    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13409        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13410        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13411
13412        synchronized(this) {
13413            // !!! TODO: currently no check here that we're already bound
13414            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13415            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13416            synchronized (stats) {
13417                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13418            }
13419
13420            // Backup agent is now in use, its package can't be stopped.
13421            try {
13422                AppGlobals.getPackageManager().setPackageStoppedState(
13423                        app.packageName, false, UserHandle.getUserId(app.uid));
13424            } catch (RemoteException e) {
13425            } catch (IllegalArgumentException e) {
13426                Slog.w(TAG, "Failed trying to unstop package "
13427                        + app.packageName + ": " + e);
13428            }
13429
13430            BackupRecord r = new BackupRecord(ss, app, backupMode);
13431            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13432                    ? new ComponentName(app.packageName, app.backupAgentName)
13433                    : new ComponentName("android", "FullBackupAgent");
13434            // startProcessLocked() returns existing proc's record if it's already running
13435            ProcessRecord proc = startProcessLocked(app.processName, app,
13436                    false, 0, "backup", hostingName, false, false, false);
13437            if (proc == null) {
13438                Slog.e(TAG, "Unable to start backup agent process " + r);
13439                return false;
13440            }
13441
13442            r.app = proc;
13443            mBackupTarget = r;
13444            mBackupAppName = app.packageName;
13445
13446            // Try not to kill the process during backup
13447            updateOomAdjLocked(proc);
13448
13449            // If the process is already attached, schedule the creation of the backup agent now.
13450            // If it is not yet live, this will be done when it attaches to the framework.
13451            if (proc.thread != null) {
13452                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13453                try {
13454                    proc.thread.scheduleCreateBackupAgent(app,
13455                            compatibilityInfoForPackageLocked(app), backupMode);
13456                } catch (RemoteException e) {
13457                    // Will time out on the backup manager side
13458                }
13459            } else {
13460                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13461            }
13462            // Invariants: at this point, the target app process exists and the application
13463            // is either already running or in the process of coming up.  mBackupTarget and
13464            // mBackupAppName describe the app, so that when it binds back to the AM we
13465            // know that it's scheduled for a backup-agent operation.
13466        }
13467
13468        return true;
13469    }
13470
13471    @Override
13472    public void clearPendingBackup() {
13473        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13474        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13475
13476        synchronized (this) {
13477            mBackupTarget = null;
13478            mBackupAppName = null;
13479        }
13480    }
13481
13482    // A backup agent has just come up
13483    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13484        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13485                + " = " + agent);
13486
13487        synchronized(this) {
13488            if (!agentPackageName.equals(mBackupAppName)) {
13489                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13490                return;
13491            }
13492        }
13493
13494        long oldIdent = Binder.clearCallingIdentity();
13495        try {
13496            IBackupManager bm = IBackupManager.Stub.asInterface(
13497                    ServiceManager.getService(Context.BACKUP_SERVICE));
13498            bm.agentConnected(agentPackageName, agent);
13499        } catch (RemoteException e) {
13500            // can't happen; the backup manager service is local
13501        } catch (Exception e) {
13502            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13503            e.printStackTrace();
13504        } finally {
13505            Binder.restoreCallingIdentity(oldIdent);
13506        }
13507    }
13508
13509    // done with this agent
13510    public void unbindBackupAgent(ApplicationInfo appInfo) {
13511        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13512        if (appInfo == null) {
13513            Slog.w(TAG, "unbind backup agent for null app");
13514            return;
13515        }
13516
13517        synchronized(this) {
13518            try {
13519                if (mBackupAppName == null) {
13520                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13521                    return;
13522                }
13523
13524                if (!mBackupAppName.equals(appInfo.packageName)) {
13525                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13526                    return;
13527                }
13528
13529                // Not backing this app up any more; reset its OOM adjustment
13530                final ProcessRecord proc = mBackupTarget.app;
13531                updateOomAdjLocked(proc);
13532
13533                // If the app crashed during backup, 'thread' will be null here
13534                if (proc.thread != null) {
13535                    try {
13536                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13537                                compatibilityInfoForPackageLocked(appInfo));
13538                    } catch (Exception e) {
13539                        Slog.e(TAG, "Exception when unbinding backup agent:");
13540                        e.printStackTrace();
13541                    }
13542                }
13543            } finally {
13544                mBackupTarget = null;
13545                mBackupAppName = null;
13546            }
13547        }
13548    }
13549    // =========================================================
13550    // BROADCASTS
13551    // =========================================================
13552
13553    private final List getStickiesLocked(String action, IntentFilter filter,
13554            List cur, int userId) {
13555        final ContentResolver resolver = mContext.getContentResolver();
13556        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13557        if (stickies == null) {
13558            return cur;
13559        }
13560        final ArrayList<Intent> list = stickies.get(action);
13561        if (list == null) {
13562            return cur;
13563        }
13564        int N = list.size();
13565        for (int i=0; i<N; i++) {
13566            Intent intent = list.get(i);
13567            if (filter.match(resolver, intent, true, TAG) >= 0) {
13568                if (cur == null) {
13569                    cur = new ArrayList<Intent>();
13570                }
13571                cur.add(intent);
13572            }
13573        }
13574        return cur;
13575    }
13576
13577    boolean isPendingBroadcastProcessLocked(int pid) {
13578        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13579                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13580    }
13581
13582    void skipPendingBroadcastLocked(int pid) {
13583            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13584            for (BroadcastQueue queue : mBroadcastQueues) {
13585                queue.skipPendingBroadcastLocked(pid);
13586            }
13587    }
13588
13589    // The app just attached; send any pending broadcasts that it should receive
13590    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13591        boolean didSomething = false;
13592        for (BroadcastQueue queue : mBroadcastQueues) {
13593            didSomething |= queue.sendPendingBroadcastsLocked(app);
13594        }
13595        return didSomething;
13596    }
13597
13598    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13599            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13600        enforceNotIsolatedCaller("registerReceiver");
13601        int callingUid;
13602        int callingPid;
13603        synchronized(this) {
13604            ProcessRecord callerApp = null;
13605            if (caller != null) {
13606                callerApp = getRecordForAppLocked(caller);
13607                if (callerApp == null) {
13608                    throw new SecurityException(
13609                            "Unable to find app for caller " + caller
13610                            + " (pid=" + Binder.getCallingPid()
13611                            + ") when registering receiver " + receiver);
13612                }
13613                if (callerApp.info.uid != Process.SYSTEM_UID &&
13614                        !callerApp.pkgList.containsKey(callerPackage) &&
13615                        !"android".equals(callerPackage)) {
13616                    throw new SecurityException("Given caller package " + callerPackage
13617                            + " is not running in process " + callerApp);
13618                }
13619                callingUid = callerApp.info.uid;
13620                callingPid = callerApp.pid;
13621            } else {
13622                callerPackage = null;
13623                callingUid = Binder.getCallingUid();
13624                callingPid = Binder.getCallingPid();
13625            }
13626
13627            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13628                    true, true, "registerReceiver", callerPackage);
13629
13630            List allSticky = null;
13631
13632            // Look for any matching sticky broadcasts...
13633            Iterator actions = filter.actionsIterator();
13634            if (actions != null) {
13635                while (actions.hasNext()) {
13636                    String action = (String)actions.next();
13637                    allSticky = getStickiesLocked(action, filter, allSticky,
13638                            UserHandle.USER_ALL);
13639                    allSticky = getStickiesLocked(action, filter, allSticky,
13640                            UserHandle.getUserId(callingUid));
13641                }
13642            } else {
13643                allSticky = getStickiesLocked(null, filter, allSticky,
13644                        UserHandle.USER_ALL);
13645                allSticky = getStickiesLocked(null, filter, allSticky,
13646                        UserHandle.getUserId(callingUid));
13647            }
13648
13649            // The first sticky in the list is returned directly back to
13650            // the client.
13651            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13652
13653            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13654                    + ": " + sticky);
13655
13656            if (receiver == null) {
13657                return sticky;
13658            }
13659
13660            ReceiverList rl
13661                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13662            if (rl == null) {
13663                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13664                        userId, receiver);
13665                if (rl.app != null) {
13666                    rl.app.receivers.add(rl);
13667                } else {
13668                    try {
13669                        receiver.asBinder().linkToDeath(rl, 0);
13670                    } catch (RemoteException e) {
13671                        return sticky;
13672                    }
13673                    rl.linkedToDeath = true;
13674                }
13675                mRegisteredReceivers.put(receiver.asBinder(), rl);
13676            } else if (rl.uid != callingUid) {
13677                throw new IllegalArgumentException(
13678                        "Receiver requested to register for uid " + callingUid
13679                        + " was previously registered for uid " + rl.uid);
13680            } else if (rl.pid != callingPid) {
13681                throw new IllegalArgumentException(
13682                        "Receiver requested to register for pid " + callingPid
13683                        + " was previously registered for pid " + rl.pid);
13684            } else if (rl.userId != userId) {
13685                throw new IllegalArgumentException(
13686                        "Receiver requested to register for user " + userId
13687                        + " was previously registered for user " + rl.userId);
13688            }
13689            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13690                    permission, callingUid, userId);
13691            rl.add(bf);
13692            if (!bf.debugCheck()) {
13693                Slog.w(TAG, "==> For Dynamic broadast");
13694            }
13695            mReceiverResolver.addFilter(bf);
13696
13697            // Enqueue broadcasts for all existing stickies that match
13698            // this filter.
13699            if (allSticky != null) {
13700                ArrayList receivers = new ArrayList();
13701                receivers.add(bf);
13702
13703                int N = allSticky.size();
13704                for (int i=0; i<N; i++) {
13705                    Intent intent = (Intent)allSticky.get(i);
13706                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13707                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13708                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13709                            null, null, false, true, true, -1);
13710                    queue.enqueueParallelBroadcastLocked(r);
13711                    queue.scheduleBroadcastsLocked();
13712                }
13713            }
13714
13715            return sticky;
13716        }
13717    }
13718
13719    public void unregisterReceiver(IIntentReceiver receiver) {
13720        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13721
13722        final long origId = Binder.clearCallingIdentity();
13723        try {
13724            boolean doTrim = false;
13725
13726            synchronized(this) {
13727                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13728                if (rl != null) {
13729                    if (rl.curBroadcast != null) {
13730                        BroadcastRecord r = rl.curBroadcast;
13731                        final boolean doNext = finishReceiverLocked(
13732                                receiver.asBinder(), r.resultCode, r.resultData,
13733                                r.resultExtras, r.resultAbort);
13734                        if (doNext) {
13735                            doTrim = true;
13736                            r.queue.processNextBroadcast(false);
13737                        }
13738                    }
13739
13740                    if (rl.app != null) {
13741                        rl.app.receivers.remove(rl);
13742                    }
13743                    removeReceiverLocked(rl);
13744                    if (rl.linkedToDeath) {
13745                        rl.linkedToDeath = false;
13746                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13747                    }
13748                }
13749            }
13750
13751            // If we actually concluded any broadcasts, we might now be able
13752            // to trim the recipients' apps from our working set
13753            if (doTrim) {
13754                trimApplications();
13755                return;
13756            }
13757
13758        } finally {
13759            Binder.restoreCallingIdentity(origId);
13760        }
13761    }
13762
13763    void removeReceiverLocked(ReceiverList rl) {
13764        mRegisteredReceivers.remove(rl.receiver.asBinder());
13765        int N = rl.size();
13766        for (int i=0; i<N; i++) {
13767            mReceiverResolver.removeFilter(rl.get(i));
13768        }
13769    }
13770
13771    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13772        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13773            ProcessRecord r = mLruProcesses.get(i);
13774            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13775                try {
13776                    r.thread.dispatchPackageBroadcast(cmd, packages);
13777                } catch (RemoteException ex) {
13778                }
13779            }
13780        }
13781    }
13782
13783    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13784            int[] users) {
13785        List<ResolveInfo> receivers = null;
13786        try {
13787            HashSet<ComponentName> singleUserReceivers = null;
13788            boolean scannedFirstReceivers = false;
13789            for (int user : users) {
13790                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13791                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13792                if (user != 0 && newReceivers != null) {
13793                    // If this is not the primary user, we need to check for
13794                    // any receivers that should be filtered out.
13795                    for (int i=0; i<newReceivers.size(); i++) {
13796                        ResolveInfo ri = newReceivers.get(i);
13797                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13798                            newReceivers.remove(i);
13799                            i--;
13800                        }
13801                    }
13802                }
13803                if (newReceivers != null && newReceivers.size() == 0) {
13804                    newReceivers = null;
13805                }
13806                if (receivers == null) {
13807                    receivers = newReceivers;
13808                } else if (newReceivers != null) {
13809                    // We need to concatenate the additional receivers
13810                    // found with what we have do far.  This would be easy,
13811                    // but we also need to de-dup any receivers that are
13812                    // singleUser.
13813                    if (!scannedFirstReceivers) {
13814                        // Collect any single user receivers we had already retrieved.
13815                        scannedFirstReceivers = true;
13816                        for (int i=0; i<receivers.size(); i++) {
13817                            ResolveInfo ri = receivers.get(i);
13818                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13819                                ComponentName cn = new ComponentName(
13820                                        ri.activityInfo.packageName, ri.activityInfo.name);
13821                                if (singleUserReceivers == null) {
13822                                    singleUserReceivers = new HashSet<ComponentName>();
13823                                }
13824                                singleUserReceivers.add(cn);
13825                            }
13826                        }
13827                    }
13828                    // Add the new results to the existing results, tracking
13829                    // and de-dupping single user receivers.
13830                    for (int i=0; i<newReceivers.size(); i++) {
13831                        ResolveInfo ri = newReceivers.get(i);
13832                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13833                            ComponentName cn = new ComponentName(
13834                                    ri.activityInfo.packageName, ri.activityInfo.name);
13835                            if (singleUserReceivers == null) {
13836                                singleUserReceivers = new HashSet<ComponentName>();
13837                            }
13838                            if (!singleUserReceivers.contains(cn)) {
13839                                singleUserReceivers.add(cn);
13840                                receivers.add(ri);
13841                            }
13842                        } else {
13843                            receivers.add(ri);
13844                        }
13845                    }
13846                }
13847            }
13848        } catch (RemoteException ex) {
13849            // pm is in same process, this will never happen.
13850        }
13851        return receivers;
13852    }
13853
13854    private final int broadcastIntentLocked(ProcessRecord callerApp,
13855            String callerPackage, Intent intent, String resolvedType,
13856            IIntentReceiver resultTo, int resultCode, String resultData,
13857            Bundle map, String requiredPermission, int appOp,
13858            boolean ordered, boolean sticky, int callingPid, int callingUid,
13859            int userId) {
13860        intent = new Intent(intent);
13861
13862        // By default broadcasts do not go to stopped apps.
13863        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13864
13865        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13866            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13867            + " ordered=" + ordered + " userid=" + userId);
13868        if ((resultTo != null) && !ordered) {
13869            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13870        }
13871
13872        userId = handleIncomingUser(callingPid, callingUid, userId,
13873                true, false, "broadcast", callerPackage);
13874
13875        // Make sure that the user who is receiving this broadcast is started.
13876        // If not, we will just skip it.
13877        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13878            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13879                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13880                Slog.w(TAG, "Skipping broadcast of " + intent
13881                        + ": user " + userId + " is stopped");
13882                return ActivityManager.BROADCAST_SUCCESS;
13883            }
13884        }
13885
13886        /*
13887         * Prevent non-system code (defined here to be non-persistent
13888         * processes) from sending protected broadcasts.
13889         */
13890        int callingAppId = UserHandle.getAppId(callingUid);
13891        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13892                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13893                || callingUid == 0) {
13894            // Always okay.
13895        } else if (callerApp == null || !callerApp.persistent) {
13896            try {
13897                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13898                        intent.getAction())) {
13899                    String msg = "Permission Denial: not allowed to send broadcast "
13900                            + intent.getAction() + " from pid="
13901                            + callingPid + ", uid=" + callingUid;
13902                    Slog.w(TAG, msg);
13903                    throw new SecurityException(msg);
13904                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13905                    // Special case for compatibility: we don't want apps to send this,
13906                    // but historically it has not been protected and apps may be using it
13907                    // to poke their own app widget.  So, instead of making it protected,
13908                    // just limit it to the caller.
13909                    if (callerApp == null) {
13910                        String msg = "Permission Denial: not allowed to send broadcast "
13911                                + intent.getAction() + " from unknown caller.";
13912                        Slog.w(TAG, msg);
13913                        throw new SecurityException(msg);
13914                    } else if (intent.getComponent() != null) {
13915                        // They are good enough to send to an explicit component...  verify
13916                        // it is being sent to the calling app.
13917                        if (!intent.getComponent().getPackageName().equals(
13918                                callerApp.info.packageName)) {
13919                            String msg = "Permission Denial: not allowed to send broadcast "
13920                                    + intent.getAction() + " to "
13921                                    + intent.getComponent().getPackageName() + " from "
13922                                    + callerApp.info.packageName;
13923                            Slog.w(TAG, msg);
13924                            throw new SecurityException(msg);
13925                        }
13926                    } else {
13927                        // Limit broadcast to their own package.
13928                        intent.setPackage(callerApp.info.packageName);
13929                    }
13930                }
13931            } catch (RemoteException e) {
13932                Slog.w(TAG, "Remote exception", e);
13933                return ActivityManager.BROADCAST_SUCCESS;
13934            }
13935        }
13936
13937        // Handle special intents: if this broadcast is from the package
13938        // manager about a package being removed, we need to remove all of
13939        // its activities from the history stack.
13940        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13941                intent.getAction());
13942        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13943                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13944                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13945                || uidRemoved) {
13946            if (checkComponentPermission(
13947                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13948                    callingPid, callingUid, -1, true)
13949                    == PackageManager.PERMISSION_GRANTED) {
13950                if (uidRemoved) {
13951                    final Bundle intentExtras = intent.getExtras();
13952                    final int uid = intentExtras != null
13953                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13954                    if (uid >= 0) {
13955                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13956                        synchronized (bs) {
13957                            bs.removeUidStatsLocked(uid);
13958                        }
13959                        mAppOpsService.uidRemoved(uid);
13960                    }
13961                } else {
13962                    // If resources are unavailable just force stop all
13963                    // those packages and flush the attribute cache as well.
13964                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13965                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13966                        if (list != null && (list.length > 0)) {
13967                            for (String pkg : list) {
13968                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13969                                        "storage unmount");
13970                            }
13971                            sendPackageBroadcastLocked(
13972                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13973                        }
13974                    } else {
13975                        Uri data = intent.getData();
13976                        String ssp;
13977                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13978                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13979                                    intent.getAction());
13980                            boolean fullUninstall = removed &&
13981                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13982                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13983                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13984                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13985                                        false, fullUninstall, userId,
13986                                        removed ? "pkg removed" : "pkg changed");
13987                            }
13988                            if (removed) {
13989                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13990                                        new String[] {ssp}, userId);
13991                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13992                                    mAppOpsService.packageRemoved(
13993                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13994
13995                                    // Remove all permissions granted from/to this package
13996                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13997                                }
13998                            }
13999                        }
14000                    }
14001                }
14002            } else {
14003                String msg = "Permission Denial: " + intent.getAction()
14004                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14005                        + ", uid=" + callingUid + ")"
14006                        + " requires "
14007                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14008                Slog.w(TAG, msg);
14009                throw new SecurityException(msg);
14010            }
14011
14012        // Special case for adding a package: by default turn on compatibility
14013        // mode.
14014        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14015            Uri data = intent.getData();
14016            String ssp;
14017            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14018                mCompatModePackages.handlePackageAddedLocked(ssp,
14019                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14020            }
14021        }
14022
14023        /*
14024         * If this is the time zone changed action, queue up a message that will reset the timezone
14025         * of all currently running processes. This message will get queued up before the broadcast
14026         * happens.
14027         */
14028        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14029            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14030        }
14031
14032        /*
14033         * If the user set the time, let all running processes know.
14034         */
14035        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14036            final int is24Hour = intent.getBooleanExtra(
14037                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14038            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14039        }
14040
14041        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14042            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14043        }
14044
14045        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14046            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14047            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14048        }
14049
14050        // Add to the sticky list if requested.
14051        if (sticky) {
14052            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14053                    callingPid, callingUid)
14054                    != PackageManager.PERMISSION_GRANTED) {
14055                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14056                        + callingPid + ", uid=" + callingUid
14057                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14058                Slog.w(TAG, msg);
14059                throw new SecurityException(msg);
14060            }
14061            if (requiredPermission != null) {
14062                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14063                        + " and enforce permission " + requiredPermission);
14064                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14065            }
14066            if (intent.getComponent() != null) {
14067                throw new SecurityException(
14068                        "Sticky broadcasts can't target a specific component");
14069            }
14070            // We use userId directly here, since the "all" target is maintained
14071            // as a separate set of sticky broadcasts.
14072            if (userId != UserHandle.USER_ALL) {
14073                // But first, if this is not a broadcast to all users, then
14074                // make sure it doesn't conflict with an existing broadcast to
14075                // all users.
14076                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14077                        UserHandle.USER_ALL);
14078                if (stickies != null) {
14079                    ArrayList<Intent> list = stickies.get(intent.getAction());
14080                    if (list != null) {
14081                        int N = list.size();
14082                        int i;
14083                        for (i=0; i<N; i++) {
14084                            if (intent.filterEquals(list.get(i))) {
14085                                throw new IllegalArgumentException(
14086                                        "Sticky broadcast " + intent + " for user "
14087                                        + userId + " conflicts with existing global broadcast");
14088                            }
14089                        }
14090                    }
14091                }
14092            }
14093            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14094            if (stickies == null) {
14095                stickies = new ArrayMap<String, ArrayList<Intent>>();
14096                mStickyBroadcasts.put(userId, stickies);
14097            }
14098            ArrayList<Intent> list = stickies.get(intent.getAction());
14099            if (list == null) {
14100                list = new ArrayList<Intent>();
14101                stickies.put(intent.getAction(), list);
14102            }
14103            int N = list.size();
14104            int i;
14105            for (i=0; i<N; i++) {
14106                if (intent.filterEquals(list.get(i))) {
14107                    // This sticky already exists, replace it.
14108                    list.set(i, new Intent(intent));
14109                    break;
14110                }
14111            }
14112            if (i >= N) {
14113                list.add(new Intent(intent));
14114            }
14115        }
14116
14117        int[] users;
14118        if (userId == UserHandle.USER_ALL) {
14119            // Caller wants broadcast to go to all started users.
14120            users = mStartedUserArray;
14121        } else {
14122            // Caller wants broadcast to go to one specific user.
14123            users = new int[] {userId};
14124        }
14125
14126        // Figure out who all will receive this broadcast.
14127        List receivers = null;
14128        List<BroadcastFilter> registeredReceivers = null;
14129        // Need to resolve the intent to interested receivers...
14130        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14131                 == 0) {
14132            receivers = collectReceiverComponents(intent, resolvedType, users);
14133        }
14134        if (intent.getComponent() == null) {
14135            registeredReceivers = mReceiverResolver.queryIntent(intent,
14136                    resolvedType, false, userId);
14137        }
14138
14139        final boolean replacePending =
14140                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14141
14142        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14143                + " replacePending=" + replacePending);
14144
14145        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14146        if (!ordered && NR > 0) {
14147            // If we are not serializing this broadcast, then send the
14148            // registered receivers separately so they don't wait for the
14149            // components to be launched.
14150            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14151            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14152                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14153                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14154                    ordered, sticky, false, userId);
14155            if (DEBUG_BROADCAST) Slog.v(
14156                    TAG, "Enqueueing parallel broadcast " + r);
14157            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14158            if (!replaced) {
14159                queue.enqueueParallelBroadcastLocked(r);
14160                queue.scheduleBroadcastsLocked();
14161            }
14162            registeredReceivers = null;
14163            NR = 0;
14164        }
14165
14166        // Merge into one list.
14167        int ir = 0;
14168        if (receivers != null) {
14169            // A special case for PACKAGE_ADDED: do not allow the package
14170            // being added to see this broadcast.  This prevents them from
14171            // using this as a back door to get run as soon as they are
14172            // installed.  Maybe in the future we want to have a special install
14173            // broadcast or such for apps, but we'd like to deliberately make
14174            // this decision.
14175            String skipPackages[] = null;
14176            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14177                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14178                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14179                Uri data = intent.getData();
14180                if (data != null) {
14181                    String pkgName = data.getSchemeSpecificPart();
14182                    if (pkgName != null) {
14183                        skipPackages = new String[] { pkgName };
14184                    }
14185                }
14186            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14187                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14188            }
14189            if (skipPackages != null && (skipPackages.length > 0)) {
14190                for (String skipPackage : skipPackages) {
14191                    if (skipPackage != null) {
14192                        int NT = receivers.size();
14193                        for (int it=0; it<NT; it++) {
14194                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14195                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14196                                receivers.remove(it);
14197                                it--;
14198                                NT--;
14199                            }
14200                        }
14201                    }
14202                }
14203            }
14204
14205            int NT = receivers != null ? receivers.size() : 0;
14206            int it = 0;
14207            ResolveInfo curt = null;
14208            BroadcastFilter curr = null;
14209            while (it < NT && ir < NR) {
14210                if (curt == null) {
14211                    curt = (ResolveInfo)receivers.get(it);
14212                }
14213                if (curr == null) {
14214                    curr = registeredReceivers.get(ir);
14215                }
14216                if (curr.getPriority() >= curt.priority) {
14217                    // Insert this broadcast record into the final list.
14218                    receivers.add(it, curr);
14219                    ir++;
14220                    curr = null;
14221                    it++;
14222                    NT++;
14223                } else {
14224                    // Skip to the next ResolveInfo in the final list.
14225                    it++;
14226                    curt = null;
14227                }
14228            }
14229        }
14230        while (ir < NR) {
14231            if (receivers == null) {
14232                receivers = new ArrayList();
14233            }
14234            receivers.add(registeredReceivers.get(ir));
14235            ir++;
14236        }
14237
14238        if ((receivers != null && receivers.size() > 0)
14239                || resultTo != null) {
14240            BroadcastQueue queue = broadcastQueueForIntent(intent);
14241            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14242                    callerPackage, callingPid, callingUid, resolvedType,
14243                    requiredPermission, appOp, receivers, resultTo, resultCode,
14244                    resultData, map, ordered, sticky, false, userId);
14245            if (DEBUG_BROADCAST) Slog.v(
14246                    TAG, "Enqueueing ordered broadcast " + r
14247                    + ": prev had " + queue.mOrderedBroadcasts.size());
14248            if (DEBUG_BROADCAST) {
14249                int seq = r.intent.getIntExtra("seq", -1);
14250                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14251            }
14252            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14253            if (!replaced) {
14254                queue.enqueueOrderedBroadcastLocked(r);
14255                queue.scheduleBroadcastsLocked();
14256            }
14257        }
14258
14259        return ActivityManager.BROADCAST_SUCCESS;
14260    }
14261
14262    final Intent verifyBroadcastLocked(Intent intent) {
14263        // Refuse possible leaked file descriptors
14264        if (intent != null && intent.hasFileDescriptors() == true) {
14265            throw new IllegalArgumentException("File descriptors passed in Intent");
14266        }
14267
14268        int flags = intent.getFlags();
14269
14270        if (!mProcessesReady) {
14271            // if the caller really truly claims to know what they're doing, go
14272            // ahead and allow the broadcast without launching any receivers
14273            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14274                intent = new Intent(intent);
14275                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14276            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14277                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14278                        + " before boot completion");
14279                throw new IllegalStateException("Cannot broadcast before boot completed");
14280            }
14281        }
14282
14283        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14284            throw new IllegalArgumentException(
14285                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14286        }
14287
14288        return intent;
14289    }
14290
14291    public final int broadcastIntent(IApplicationThread caller,
14292            Intent intent, String resolvedType, IIntentReceiver resultTo,
14293            int resultCode, String resultData, Bundle map,
14294            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14295        enforceNotIsolatedCaller("broadcastIntent");
14296        synchronized(this) {
14297            intent = verifyBroadcastLocked(intent);
14298
14299            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14300            final int callingPid = Binder.getCallingPid();
14301            final int callingUid = Binder.getCallingUid();
14302            final long origId = Binder.clearCallingIdentity();
14303            int res = broadcastIntentLocked(callerApp,
14304                    callerApp != null ? callerApp.info.packageName : null,
14305                    intent, resolvedType, resultTo,
14306                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14307                    callingPid, callingUid, userId);
14308            Binder.restoreCallingIdentity(origId);
14309            return res;
14310        }
14311    }
14312
14313    int broadcastIntentInPackage(String packageName, int uid,
14314            Intent intent, String resolvedType, IIntentReceiver resultTo,
14315            int resultCode, String resultData, Bundle map,
14316            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14317        synchronized(this) {
14318            intent = verifyBroadcastLocked(intent);
14319
14320            final long origId = Binder.clearCallingIdentity();
14321            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14322                    resultTo, resultCode, resultData, map, requiredPermission,
14323                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14324            Binder.restoreCallingIdentity(origId);
14325            return res;
14326        }
14327    }
14328
14329    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14330        // Refuse possible leaked file descriptors
14331        if (intent != null && intent.hasFileDescriptors() == true) {
14332            throw new IllegalArgumentException("File descriptors passed in Intent");
14333        }
14334
14335        userId = handleIncomingUser(Binder.getCallingPid(),
14336                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14337
14338        synchronized(this) {
14339            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14340                    != PackageManager.PERMISSION_GRANTED) {
14341                String msg = "Permission Denial: unbroadcastIntent() from pid="
14342                        + Binder.getCallingPid()
14343                        + ", uid=" + Binder.getCallingUid()
14344                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14345                Slog.w(TAG, msg);
14346                throw new SecurityException(msg);
14347            }
14348            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14349            if (stickies != null) {
14350                ArrayList<Intent> list = stickies.get(intent.getAction());
14351                if (list != null) {
14352                    int N = list.size();
14353                    int i;
14354                    for (i=0; i<N; i++) {
14355                        if (intent.filterEquals(list.get(i))) {
14356                            list.remove(i);
14357                            break;
14358                        }
14359                    }
14360                    if (list.size() <= 0) {
14361                        stickies.remove(intent.getAction());
14362                    }
14363                }
14364                if (stickies.size() <= 0) {
14365                    mStickyBroadcasts.remove(userId);
14366                }
14367            }
14368        }
14369    }
14370
14371    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14372            String resultData, Bundle resultExtras, boolean resultAbort) {
14373        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14374        if (r == null) {
14375            Slog.w(TAG, "finishReceiver called but not found on queue");
14376            return false;
14377        }
14378
14379        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14380    }
14381
14382    void backgroundServicesFinishedLocked(int userId) {
14383        for (BroadcastQueue queue : mBroadcastQueues) {
14384            queue.backgroundServicesFinishedLocked(userId);
14385        }
14386    }
14387
14388    public void finishReceiver(IBinder who, int resultCode, String resultData,
14389            Bundle resultExtras, boolean resultAbort) {
14390        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14391
14392        // Refuse possible leaked file descriptors
14393        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14394            throw new IllegalArgumentException("File descriptors passed in Bundle");
14395        }
14396
14397        final long origId = Binder.clearCallingIdentity();
14398        try {
14399            boolean doNext = false;
14400            BroadcastRecord r;
14401
14402            synchronized(this) {
14403                r = broadcastRecordForReceiverLocked(who);
14404                if (r != null) {
14405                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14406                        resultData, resultExtras, resultAbort, true);
14407                }
14408            }
14409
14410            if (doNext) {
14411                r.queue.processNextBroadcast(false);
14412            }
14413            trimApplications();
14414        } finally {
14415            Binder.restoreCallingIdentity(origId);
14416        }
14417    }
14418
14419    // =========================================================
14420    // INSTRUMENTATION
14421    // =========================================================
14422
14423    public boolean startInstrumentation(ComponentName className,
14424            String profileFile, int flags, Bundle arguments,
14425            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14426            int userId, String abiOverride) {
14427        enforceNotIsolatedCaller("startInstrumentation");
14428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14429                userId, false, true, "startInstrumentation", null);
14430        // Refuse possible leaked file descriptors
14431        if (arguments != null && arguments.hasFileDescriptors()) {
14432            throw new IllegalArgumentException("File descriptors passed in Bundle");
14433        }
14434
14435        synchronized(this) {
14436            InstrumentationInfo ii = null;
14437            ApplicationInfo ai = null;
14438            try {
14439                ii = mContext.getPackageManager().getInstrumentationInfo(
14440                    className, STOCK_PM_FLAGS);
14441                ai = AppGlobals.getPackageManager().getApplicationInfo(
14442                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14443            } catch (PackageManager.NameNotFoundException e) {
14444            } catch (RemoteException e) {
14445            }
14446            if (ii == null) {
14447                reportStartInstrumentationFailure(watcher, className,
14448                        "Unable to find instrumentation info for: " + className);
14449                return false;
14450            }
14451            if (ai == null) {
14452                reportStartInstrumentationFailure(watcher, className,
14453                        "Unable to find instrumentation target package: " + ii.targetPackage);
14454                return false;
14455            }
14456
14457            int match = mContext.getPackageManager().checkSignatures(
14458                    ii.targetPackage, ii.packageName);
14459            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14460                String msg = "Permission Denial: starting instrumentation "
14461                        + className + " from pid="
14462                        + Binder.getCallingPid()
14463                        + ", uid=" + Binder.getCallingPid()
14464                        + " not allowed because package " + ii.packageName
14465                        + " does not have a signature matching the target "
14466                        + ii.targetPackage;
14467                reportStartInstrumentationFailure(watcher, className, msg);
14468                throw new SecurityException(msg);
14469            }
14470
14471            final long origId = Binder.clearCallingIdentity();
14472            // Instrumentation can kill and relaunch even persistent processes
14473            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14474                    "start instr");
14475            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14476            app.instrumentationClass = className;
14477            app.instrumentationInfo = ai;
14478            app.instrumentationProfileFile = profileFile;
14479            app.instrumentationArguments = arguments;
14480            app.instrumentationWatcher = watcher;
14481            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14482            app.instrumentationResultClass = className;
14483            Binder.restoreCallingIdentity(origId);
14484        }
14485
14486        return true;
14487    }
14488
14489    /**
14490     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14491     * error to the logs, but if somebody is watching, send the report there too.  This enables
14492     * the "am" command to report errors with more information.
14493     *
14494     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14495     * @param cn The component name of the instrumentation.
14496     * @param report The error report.
14497     */
14498    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14499            ComponentName cn, String report) {
14500        Slog.w(TAG, report);
14501        try {
14502            if (watcher != null) {
14503                Bundle results = new Bundle();
14504                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14505                results.putString("Error", report);
14506                watcher.instrumentationStatus(cn, -1, results);
14507            }
14508        } catch (RemoteException e) {
14509            Slog.w(TAG, e);
14510        }
14511    }
14512
14513    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14514        if (app.instrumentationWatcher != null) {
14515            try {
14516                // NOTE:  IInstrumentationWatcher *must* be oneway here
14517                app.instrumentationWatcher.instrumentationFinished(
14518                    app.instrumentationClass,
14519                    resultCode,
14520                    results);
14521            } catch (RemoteException e) {
14522            }
14523        }
14524        if (app.instrumentationUiAutomationConnection != null) {
14525            try {
14526                app.instrumentationUiAutomationConnection.shutdown();
14527            } catch (RemoteException re) {
14528                /* ignore */
14529            }
14530            // Only a UiAutomation can set this flag and now that
14531            // it is finished we make sure it is reset to its default.
14532            mUserIsMonkey = false;
14533        }
14534        app.instrumentationWatcher = null;
14535        app.instrumentationUiAutomationConnection = null;
14536        app.instrumentationClass = null;
14537        app.instrumentationInfo = null;
14538        app.instrumentationProfileFile = null;
14539        app.instrumentationArguments = null;
14540
14541        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14542                "finished inst");
14543    }
14544
14545    public void finishInstrumentation(IApplicationThread target,
14546            int resultCode, Bundle results) {
14547        int userId = UserHandle.getCallingUserId();
14548        // Refuse possible leaked file descriptors
14549        if (results != null && results.hasFileDescriptors()) {
14550            throw new IllegalArgumentException("File descriptors passed in Intent");
14551        }
14552
14553        synchronized(this) {
14554            ProcessRecord app = getRecordForAppLocked(target);
14555            if (app == null) {
14556                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14557                return;
14558            }
14559            final long origId = Binder.clearCallingIdentity();
14560            finishInstrumentationLocked(app, resultCode, results);
14561            Binder.restoreCallingIdentity(origId);
14562        }
14563    }
14564
14565    // =========================================================
14566    // CONFIGURATION
14567    // =========================================================
14568
14569    public ConfigurationInfo getDeviceConfigurationInfo() {
14570        ConfigurationInfo config = new ConfigurationInfo();
14571        synchronized (this) {
14572            config.reqTouchScreen = mConfiguration.touchscreen;
14573            config.reqKeyboardType = mConfiguration.keyboard;
14574            config.reqNavigation = mConfiguration.navigation;
14575            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14576                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14577                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14578            }
14579            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14580                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14581                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14582            }
14583            config.reqGlEsVersion = GL_ES_VERSION;
14584        }
14585        return config;
14586    }
14587
14588    ActivityStack getFocusedStack() {
14589        return mStackSupervisor.getFocusedStack();
14590    }
14591
14592    public Configuration getConfiguration() {
14593        Configuration ci;
14594        synchronized(this) {
14595            ci = new Configuration(mConfiguration);
14596        }
14597        return ci;
14598    }
14599
14600    public void updatePersistentConfiguration(Configuration values) {
14601        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14602                "updateConfiguration()");
14603        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14604                "updateConfiguration()");
14605        if (values == null) {
14606            throw new NullPointerException("Configuration must not be null");
14607        }
14608
14609        synchronized(this) {
14610            final long origId = Binder.clearCallingIdentity();
14611            updateConfigurationLocked(values, null, true, false);
14612            Binder.restoreCallingIdentity(origId);
14613        }
14614    }
14615
14616    public void updateConfiguration(Configuration values) {
14617        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14618                "updateConfiguration()");
14619
14620        synchronized(this) {
14621            if (values == null && mWindowManager != null) {
14622                // sentinel: fetch the current configuration from the window manager
14623                values = mWindowManager.computeNewConfiguration();
14624            }
14625
14626            if (mWindowManager != null) {
14627                mProcessList.applyDisplaySize(mWindowManager);
14628            }
14629
14630            final long origId = Binder.clearCallingIdentity();
14631            if (values != null) {
14632                Settings.System.clearConfiguration(values);
14633            }
14634            updateConfigurationLocked(values, null, false, false);
14635            Binder.restoreCallingIdentity(origId);
14636        }
14637    }
14638
14639    /**
14640     * Do either or both things: (1) change the current configuration, and (2)
14641     * make sure the given activity is running with the (now) current
14642     * configuration.  Returns true if the activity has been left running, or
14643     * false if <var>starting</var> is being destroyed to match the new
14644     * configuration.
14645     * @param persistent TODO
14646     */
14647    boolean updateConfigurationLocked(Configuration values,
14648            ActivityRecord starting, boolean persistent, boolean initLocale) {
14649        int changes = 0;
14650
14651        if (values != null) {
14652            Configuration newConfig = new Configuration(mConfiguration);
14653            changes = newConfig.updateFrom(values);
14654            if (changes != 0) {
14655                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14656                    Slog.i(TAG, "Updating configuration to: " + values);
14657                }
14658
14659                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14660
14661                if (values.locale != null && !initLocale) {
14662                    saveLocaleLocked(values.locale,
14663                                     !values.locale.equals(mConfiguration.locale),
14664                                     values.userSetLocale);
14665                }
14666
14667                mConfigurationSeq++;
14668                if (mConfigurationSeq <= 0) {
14669                    mConfigurationSeq = 1;
14670                }
14671                newConfig.seq = mConfigurationSeq;
14672                mConfiguration = newConfig;
14673                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14674                mUsageStatsService.noteStartConfig(newConfig);
14675
14676                final Configuration configCopy = new Configuration(mConfiguration);
14677
14678                // TODO: If our config changes, should we auto dismiss any currently
14679                // showing dialogs?
14680                mShowDialogs = shouldShowDialogs(newConfig);
14681
14682                AttributeCache ac = AttributeCache.instance();
14683                if (ac != null) {
14684                    ac.updateConfiguration(configCopy);
14685                }
14686
14687                // Make sure all resources in our process are updated
14688                // right now, so that anyone who is going to retrieve
14689                // resource values after we return will be sure to get
14690                // the new ones.  This is especially important during
14691                // boot, where the first config change needs to guarantee
14692                // all resources have that config before following boot
14693                // code is executed.
14694                mSystemThread.applyConfigurationToResources(configCopy);
14695
14696                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14697                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14698                    msg.obj = new Configuration(configCopy);
14699                    mHandler.sendMessage(msg);
14700                }
14701
14702                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14703                    ProcessRecord app = mLruProcesses.get(i);
14704                    try {
14705                        if (app.thread != null) {
14706                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14707                                    + app.processName + " new config " + mConfiguration);
14708                            app.thread.scheduleConfigurationChanged(configCopy);
14709                        }
14710                    } catch (Exception e) {
14711                    }
14712                }
14713                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14714                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14715                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14716                        | Intent.FLAG_RECEIVER_FOREGROUND);
14717                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14718                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14719                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14720                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14721                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14722                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14723                    broadcastIntentLocked(null, null, intent,
14724                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14725                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14726                }
14727            }
14728        }
14729
14730        boolean kept = true;
14731        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14732        // mainStack is null during startup.
14733        if (mainStack != null) {
14734            if (changes != 0 && starting == null) {
14735                // If the configuration changed, and the caller is not already
14736                // in the process of starting an activity, then find the top
14737                // activity to check if its configuration needs to change.
14738                starting = mainStack.topRunningActivityLocked(null);
14739            }
14740
14741            if (starting != null) {
14742                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14743                // And we need to make sure at this point that all other activities
14744                // are made visible with the correct configuration.
14745                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14746            }
14747        }
14748
14749        if (values != null && mWindowManager != null) {
14750            mWindowManager.setNewConfiguration(mConfiguration);
14751        }
14752
14753        return kept;
14754    }
14755
14756    /**
14757     * Decide based on the configuration whether we should shouw the ANR,
14758     * crash, etc dialogs.  The idea is that if there is no affordnace to
14759     * press the on-screen buttons, we shouldn't show the dialog.
14760     *
14761     * A thought: SystemUI might also want to get told about this, the Power
14762     * dialog / global actions also might want different behaviors.
14763     */
14764    private static final boolean shouldShowDialogs(Configuration config) {
14765        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14766                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14767    }
14768
14769    /**
14770     * Save the locale.  You must be inside a synchronized (this) block.
14771     */
14772    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14773        if(isDiff) {
14774            SystemProperties.set("user.language", l.getLanguage());
14775            SystemProperties.set("user.region", l.getCountry());
14776        }
14777
14778        if(isPersist) {
14779            SystemProperties.set("persist.sys.language", l.getLanguage());
14780            SystemProperties.set("persist.sys.country", l.getCountry());
14781            SystemProperties.set("persist.sys.localevar", l.getVariant());
14782        }
14783    }
14784
14785    @Override
14786    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14787        ActivityRecord srec = ActivityRecord.forToken(token);
14788        return srec != null && srec.task.affinity != null &&
14789                srec.task.affinity.equals(destAffinity);
14790    }
14791
14792    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14793            Intent resultData) {
14794
14795        synchronized (this) {
14796            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14797            if (stack != null) {
14798                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14799            }
14800            return false;
14801        }
14802    }
14803
14804    public int getLaunchedFromUid(IBinder activityToken) {
14805        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14806        if (srec == null) {
14807            return -1;
14808        }
14809        return srec.launchedFromUid;
14810    }
14811
14812    public String getLaunchedFromPackage(IBinder activityToken) {
14813        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14814        if (srec == null) {
14815            return null;
14816        }
14817        return srec.launchedFromPackage;
14818    }
14819
14820    // =========================================================
14821    // LIFETIME MANAGEMENT
14822    // =========================================================
14823
14824    // Returns which broadcast queue the app is the current [or imminent] receiver
14825    // on, or 'null' if the app is not an active broadcast recipient.
14826    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14827        BroadcastRecord r = app.curReceiver;
14828        if (r != null) {
14829            return r.queue;
14830        }
14831
14832        // It's not the current receiver, but it might be starting up to become one
14833        synchronized (this) {
14834            for (BroadcastQueue queue : mBroadcastQueues) {
14835                r = queue.mPendingBroadcast;
14836                if (r != null && r.curApp == app) {
14837                    // found it; report which queue it's in
14838                    return queue;
14839                }
14840            }
14841        }
14842
14843        return null;
14844    }
14845
14846    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14847            boolean doingAll, long now) {
14848        if (mAdjSeq == app.adjSeq) {
14849            // This adjustment has already been computed.
14850            return app.curRawAdj;
14851        }
14852
14853        if (app.thread == null) {
14854            app.adjSeq = mAdjSeq;
14855            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14856            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14857            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14858        }
14859
14860        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14861        app.adjSource = null;
14862        app.adjTarget = null;
14863        app.empty = false;
14864        app.cached = false;
14865
14866        final int activitiesSize = app.activities.size();
14867
14868        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14869            // The max adjustment doesn't allow this app to be anything
14870            // below foreground, so it is not worth doing work for it.
14871            app.adjType = "fixed";
14872            app.adjSeq = mAdjSeq;
14873            app.curRawAdj = app.maxAdj;
14874            app.foregroundActivities = false;
14875            app.keeping = true;
14876            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14877            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14878            // System processes can do UI, and when they do we want to have
14879            // them trim their memory after the user leaves the UI.  To
14880            // facilitate this, here we need to determine whether or not it
14881            // is currently showing UI.
14882            app.systemNoUi = true;
14883            if (app == TOP_APP) {
14884                app.systemNoUi = false;
14885            } else if (activitiesSize > 0) {
14886                for (int j = 0; j < activitiesSize; j++) {
14887                    final ActivityRecord r = app.activities.get(j);
14888                    if (r.visible) {
14889                        app.systemNoUi = false;
14890                    }
14891                }
14892            }
14893            if (!app.systemNoUi) {
14894                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14895            }
14896            return (app.curAdj=app.maxAdj);
14897        }
14898
14899        app.keeping = false;
14900        app.systemNoUi = false;
14901
14902        // Determine the importance of the process, starting with most
14903        // important to least, and assign an appropriate OOM adjustment.
14904        int adj;
14905        int schedGroup;
14906        int procState;
14907        boolean foregroundActivities = false;
14908        boolean interesting = false;
14909        BroadcastQueue queue;
14910        if (app == TOP_APP) {
14911            // The last app on the list is the foreground app.
14912            adj = ProcessList.FOREGROUND_APP_ADJ;
14913            schedGroup = Process.THREAD_GROUP_DEFAULT;
14914            app.adjType = "top-activity";
14915            foregroundActivities = true;
14916            interesting = true;
14917            procState = ActivityManager.PROCESS_STATE_TOP;
14918        } else if (app.instrumentationClass != null) {
14919            // Don't want to kill running instrumentation.
14920            adj = ProcessList.FOREGROUND_APP_ADJ;
14921            schedGroup = Process.THREAD_GROUP_DEFAULT;
14922            app.adjType = "instrumentation";
14923            interesting = true;
14924            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14925        } else if ((queue = isReceivingBroadcast(app)) != null) {
14926            // An app that is currently receiving a broadcast also
14927            // counts as being in the foreground for OOM killer purposes.
14928            // It's placed in a sched group based on the nature of the
14929            // broadcast as reflected by which queue it's active in.
14930            adj = ProcessList.FOREGROUND_APP_ADJ;
14931            schedGroup = (queue == mFgBroadcastQueue)
14932                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14933            app.adjType = "broadcast";
14934            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14935        } else if (app.executingServices.size() > 0) {
14936            // An app that is currently executing a service callback also
14937            // counts as being in the foreground.
14938            adj = ProcessList.FOREGROUND_APP_ADJ;
14939            schedGroup = app.execServicesFg ?
14940                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14941            app.adjType = "exec-service";
14942            procState = ActivityManager.PROCESS_STATE_SERVICE;
14943            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14944        } else {
14945            // As far as we know the process is empty.  We may change our mind later.
14946            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14947            // At this point we don't actually know the adjustment.  Use the cached adj
14948            // value that the caller wants us to.
14949            adj = cachedAdj;
14950            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14951            app.cached = true;
14952            app.empty = true;
14953            app.adjType = "cch-empty";
14954        }
14955
14956        // Examine all activities if not already foreground.
14957        if (!foregroundActivities && activitiesSize > 0) {
14958            for (int j = 0; j < activitiesSize; j++) {
14959                final ActivityRecord r = app.activities.get(j);
14960                if (r.app != app) {
14961                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14962                            + app + "?!?");
14963                    continue;
14964                }
14965                if (r.visible) {
14966                    // App has a visible activity; only upgrade adjustment.
14967                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14968                        adj = ProcessList.VISIBLE_APP_ADJ;
14969                        app.adjType = "visible";
14970                    }
14971                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14972                        procState = ActivityManager.PROCESS_STATE_TOP;
14973                    }
14974                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14975                    app.cached = false;
14976                    app.empty = false;
14977                    foregroundActivities = true;
14978                    break;
14979                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14980                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14981                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14982                        app.adjType = "pausing";
14983                    }
14984                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14985                        procState = ActivityManager.PROCESS_STATE_TOP;
14986                    }
14987                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14988                    app.cached = false;
14989                    app.empty = false;
14990                    foregroundActivities = true;
14991                } else if (r.state == ActivityState.STOPPING) {
14992                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14993                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14994                        app.adjType = "stopping";
14995                    }
14996                    // For the process state, we will at this point consider the
14997                    // process to be cached.  It will be cached either as an activity
14998                    // or empty depending on whether the activity is finishing.  We do
14999                    // this so that we can treat the process as cached for purposes of
15000                    // memory trimming (determing current memory level, trim command to
15001                    // send to process) since there can be an arbitrary number of stopping
15002                    // processes and they should soon all go into the cached state.
15003                    if (!r.finishing) {
15004                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15005                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15006                        }
15007                    }
15008                    app.cached = false;
15009                    app.empty = false;
15010                    foregroundActivities = true;
15011                } else {
15012                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15013                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15014                        app.adjType = "cch-act";
15015                    }
15016                }
15017            }
15018        }
15019
15020        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15021            if (app.foregroundServices) {
15022                // The user is aware of this app, so make it visible.
15023                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15024                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15025                app.cached = false;
15026                app.adjType = "fg-service";
15027                schedGroup = Process.THREAD_GROUP_DEFAULT;
15028            } else if (app.forcingToForeground != null) {
15029                // The user is aware of this app, so make it visible.
15030                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15031                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15032                app.cached = false;
15033                app.adjType = "force-fg";
15034                app.adjSource = app.forcingToForeground;
15035                schedGroup = Process.THREAD_GROUP_DEFAULT;
15036            }
15037        }
15038
15039        if (app.foregroundServices) {
15040            interesting = true;
15041        }
15042
15043        if (app == mHeavyWeightProcess) {
15044            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15045                // We don't want to kill the current heavy-weight process.
15046                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15047                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15048                app.cached = false;
15049                app.adjType = "heavy";
15050            }
15051            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15052                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15053            }
15054        }
15055
15056        if (app == mHomeProcess) {
15057            if (adj > ProcessList.HOME_APP_ADJ) {
15058                // This process is hosting what we currently consider to be the
15059                // home app, so we don't want to let it go into the background.
15060                adj = ProcessList.HOME_APP_ADJ;
15061                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15062                app.cached = false;
15063                app.adjType = "home";
15064            }
15065            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15066                procState = ActivityManager.PROCESS_STATE_HOME;
15067            }
15068        }
15069
15070        if (app == mPreviousProcess && app.activities.size() > 0) {
15071            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15072                // This was the previous process that showed UI to the user.
15073                // We want to try to keep it around more aggressively, to give
15074                // a good experience around switching between two apps.
15075                adj = ProcessList.PREVIOUS_APP_ADJ;
15076                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15077                app.cached = false;
15078                app.adjType = "previous";
15079            }
15080            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15081                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15082            }
15083        }
15084
15085        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15086                + " reason=" + app.adjType);
15087
15088        // By default, we use the computed adjustment.  It may be changed if
15089        // there are applications dependent on our services or providers, but
15090        // this gives us a baseline and makes sure we don't get into an
15091        // infinite recursion.
15092        app.adjSeq = mAdjSeq;
15093        app.curRawAdj = adj;
15094        app.hasStartedServices = false;
15095
15096        if (mBackupTarget != null && app == mBackupTarget.app) {
15097            // If possible we want to avoid killing apps while they're being backed up
15098            if (adj > ProcessList.BACKUP_APP_ADJ) {
15099                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15100                adj = ProcessList.BACKUP_APP_ADJ;
15101                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15102                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15103                }
15104                app.adjType = "backup";
15105                app.cached = false;
15106            }
15107            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15108                procState = ActivityManager.PROCESS_STATE_BACKUP;
15109            }
15110        }
15111
15112        boolean mayBeTop = false;
15113
15114        for (int is = app.services.size()-1;
15115                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15116                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15117                        || procState > ActivityManager.PROCESS_STATE_TOP);
15118                is--) {
15119            ServiceRecord s = app.services.valueAt(is);
15120            if (s.startRequested) {
15121                app.hasStartedServices = true;
15122                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15123                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15124                }
15125                if (app.hasShownUi && app != mHomeProcess) {
15126                    // If this process has shown some UI, let it immediately
15127                    // go to the LRU list because it may be pretty heavy with
15128                    // UI stuff.  We'll tag it with a label just to help
15129                    // debug and understand what is going on.
15130                    if (adj > ProcessList.SERVICE_ADJ) {
15131                        app.adjType = "cch-started-ui-services";
15132                    }
15133                } else {
15134                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15135                        // This service has seen some activity within
15136                        // recent memory, so we will keep its process ahead
15137                        // of the background processes.
15138                        if (adj > ProcessList.SERVICE_ADJ) {
15139                            adj = ProcessList.SERVICE_ADJ;
15140                            app.adjType = "started-services";
15141                            app.cached = false;
15142                        }
15143                    }
15144                    // If we have let the service slide into the background
15145                    // state, still have some text describing what it is doing
15146                    // even though the service no longer has an impact.
15147                    if (adj > ProcessList.SERVICE_ADJ) {
15148                        app.adjType = "cch-started-services";
15149                    }
15150                }
15151                // Don't kill this process because it is doing work; it
15152                // has said it is doing work.
15153                app.keeping = true;
15154            }
15155            for (int conni = s.connections.size()-1;
15156                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15157                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15158                            || procState > ActivityManager.PROCESS_STATE_TOP);
15159                    conni--) {
15160                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15161                for (int i = 0;
15162                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15163                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15164                                || procState > ActivityManager.PROCESS_STATE_TOP);
15165                        i++) {
15166                    // XXX should compute this based on the max of
15167                    // all connected clients.
15168                    ConnectionRecord cr = clist.get(i);
15169                    if (cr.binding.client == app) {
15170                        // Binding to ourself is not interesting.
15171                        continue;
15172                    }
15173                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15174                        ProcessRecord client = cr.binding.client;
15175                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15176                                TOP_APP, doingAll, now);
15177                        int clientProcState = client.curProcState;
15178                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15179                            // If the other app is cached for any reason, for purposes here
15180                            // we are going to consider it empty.  The specific cached state
15181                            // doesn't propagate except under certain conditions.
15182                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15183                        }
15184                        String adjType = null;
15185                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15186                            // Not doing bind OOM management, so treat
15187                            // this guy more like a started service.
15188                            if (app.hasShownUi && app != mHomeProcess) {
15189                                // If this process has shown some UI, let it immediately
15190                                // go to the LRU list because it may be pretty heavy with
15191                                // UI stuff.  We'll tag it with a label just to help
15192                                // debug and understand what is going on.
15193                                if (adj > clientAdj) {
15194                                    adjType = "cch-bound-ui-services";
15195                                }
15196                                app.cached = false;
15197                                clientAdj = adj;
15198                                clientProcState = procState;
15199                            } else {
15200                                if (now >= (s.lastActivity
15201                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15202                                    // This service has not seen activity within
15203                                    // recent memory, so allow it to drop to the
15204                                    // LRU list if there is no other reason to keep
15205                                    // it around.  We'll also tag it with a label just
15206                                    // to help debug and undertand what is going on.
15207                                    if (adj > clientAdj) {
15208                                        adjType = "cch-bound-services";
15209                                    }
15210                                    clientAdj = adj;
15211                                }
15212                            }
15213                        }
15214                        if (adj > clientAdj) {
15215                            // If this process has recently shown UI, and
15216                            // the process that is binding to it is less
15217                            // important than being visible, then we don't
15218                            // care about the binding as much as we care
15219                            // about letting this process get into the LRU
15220                            // list to be killed and restarted if needed for
15221                            // memory.
15222                            if (app.hasShownUi && app != mHomeProcess
15223                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15224                                adjType = "cch-bound-ui-services";
15225                            } else {
15226                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15227                                        |Context.BIND_IMPORTANT)) != 0) {
15228                                    adj = clientAdj;
15229                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15230                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15231                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15232                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15233                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15234                                    adj = clientAdj;
15235                                } else {
15236                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15237                                        adj = ProcessList.VISIBLE_APP_ADJ;
15238                                    }
15239                                }
15240                                if (!client.cached) {
15241                                    app.cached = false;
15242                                }
15243                                if (client.keeping) {
15244                                    app.keeping = true;
15245                                }
15246                                adjType = "service";
15247                            }
15248                        }
15249                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15250                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15251                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15252                            }
15253                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15254                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15255                                    // Special handling of clients who are in the top state.
15256                                    // We *may* want to consider this process to be in the
15257                                    // top state as well, but only if there is not another
15258                                    // reason for it to be running.  Being on the top is a
15259                                    // special state, meaning you are specifically running
15260                                    // for the current top app.  If the process is already
15261                                    // running in the background for some other reason, it
15262                                    // is more important to continue considering it to be
15263                                    // in the background state.
15264                                    mayBeTop = true;
15265                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15266                                } else {
15267                                    // Special handling for above-top states (persistent
15268                                    // processes).  These should not bring the current process
15269                                    // into the top state, since they are not on top.  Instead
15270                                    // give them the best state after that.
15271                                    clientProcState =
15272                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15273                                }
15274                            }
15275                        } else {
15276                            if (clientProcState <
15277                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15278                                clientProcState =
15279                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15280                            }
15281                        }
15282                        if (procState > clientProcState) {
15283                            procState = clientProcState;
15284                        }
15285                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15286                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15287                            app.pendingUiClean = true;
15288                        }
15289                        if (adjType != null) {
15290                            app.adjType = adjType;
15291                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15292                                    .REASON_SERVICE_IN_USE;
15293                            app.adjSource = cr.binding.client;
15294                            app.adjSourceOom = clientAdj;
15295                            app.adjTarget = s.name;
15296                        }
15297                    }
15298                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15299                        app.treatLikeActivity = true;
15300                    }
15301                    final ActivityRecord a = cr.activity;
15302                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15303                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15304                                (a.visible || a.state == ActivityState.RESUMED
15305                                 || a.state == ActivityState.PAUSING)) {
15306                            adj = ProcessList.FOREGROUND_APP_ADJ;
15307                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15308                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15309                            }
15310                            app.cached = false;
15311                            app.adjType = "service";
15312                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15313                                    .REASON_SERVICE_IN_USE;
15314                            app.adjSource = a;
15315                            app.adjSourceOom = adj;
15316                            app.adjTarget = s.name;
15317                        }
15318                    }
15319                }
15320            }
15321        }
15322
15323        for (int provi = app.pubProviders.size()-1;
15324                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15325                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15326                        || procState > ActivityManager.PROCESS_STATE_TOP);
15327                provi--) {
15328            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15329            for (int i = cpr.connections.size()-1;
15330                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15331                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15332                            || procState > ActivityManager.PROCESS_STATE_TOP);
15333                    i--) {
15334                ContentProviderConnection conn = cpr.connections.get(i);
15335                ProcessRecord client = conn.client;
15336                if (client == app) {
15337                    // Being our own client is not interesting.
15338                    continue;
15339                }
15340                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15341                int clientProcState = client.curProcState;
15342                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15343                    // If the other app is cached for any reason, for purposes here
15344                    // we are going to consider it empty.
15345                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15346                }
15347                if (adj > clientAdj) {
15348                    if (app.hasShownUi && app != mHomeProcess
15349                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15350                        app.adjType = "cch-ui-provider";
15351                    } else {
15352                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15353                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15354                        app.adjType = "provider";
15355                    }
15356                    app.cached &= client.cached;
15357                    app.keeping |= client.keeping;
15358                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15359                            .REASON_PROVIDER_IN_USE;
15360                    app.adjSource = client;
15361                    app.adjSourceOom = clientAdj;
15362                    app.adjTarget = cpr.name;
15363                }
15364                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15365                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15366                        // Special handling of clients who are in the top state.
15367                        // We *may* want to consider this process to be in the
15368                        // top state as well, but only if there is not another
15369                        // reason for it to be running.  Being on the top is a
15370                        // special state, meaning you are specifically running
15371                        // for the current top app.  If the process is already
15372                        // running in the background for some other reason, it
15373                        // is more important to continue considering it to be
15374                        // in the background state.
15375                        mayBeTop = true;
15376                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15377                    } else {
15378                        // Special handling for above-top states (persistent
15379                        // processes).  These should not bring the current process
15380                        // into the top state, since they are not on top.  Instead
15381                        // give them the best state after that.
15382                        clientProcState =
15383                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15384                    }
15385                }
15386                if (procState > clientProcState) {
15387                    procState = clientProcState;
15388                }
15389                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15390                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15391                }
15392            }
15393            // If the provider has external (non-framework) process
15394            // dependencies, ensure that its adjustment is at least
15395            // FOREGROUND_APP_ADJ.
15396            if (cpr.hasExternalProcessHandles()) {
15397                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15398                    adj = ProcessList.FOREGROUND_APP_ADJ;
15399                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15400                    app.cached = false;
15401                    app.keeping = true;
15402                    app.adjType = "provider";
15403                    app.adjTarget = cpr.name;
15404                }
15405                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15406                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15407                }
15408            }
15409        }
15410
15411        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15412            // A client of one of our services or providers is in the top state.  We
15413            // *may* want to be in the top state, but not if we are already running in
15414            // the background for some other reason.  For the decision here, we are going
15415            // to pick out a few specific states that we want to remain in when a client
15416            // is top (states that tend to be longer-term) and otherwise allow it to go
15417            // to the top state.
15418            switch (procState) {
15419                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15420                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15421                case ActivityManager.PROCESS_STATE_SERVICE:
15422                    // These all are longer-term states, so pull them up to the top
15423                    // of the background states, but not all the way to the top state.
15424                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15425                    break;
15426                default:
15427                    // Otherwise, top is a better choice, so take it.
15428                    procState = ActivityManager.PROCESS_STATE_TOP;
15429                    break;
15430            }
15431        }
15432
15433        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15434            if (app.hasClientActivities) {
15435                // This is a cached process, but with client activities.  Mark it so.
15436                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15437                app.adjType = "cch-client-act";
15438            } else if (app.treatLikeActivity) {
15439                // This is a cached process, but somebody wants us to treat it like it has
15440                // an activity, okay!
15441                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15442                app.adjType = "cch-as-act";
15443            }
15444        }
15445
15446        if (adj == ProcessList.SERVICE_ADJ) {
15447            if (doingAll) {
15448                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15449                mNewNumServiceProcs++;
15450                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15451                if (!app.serviceb) {
15452                    // This service isn't far enough down on the LRU list to
15453                    // normally be a B service, but if we are low on RAM and it
15454                    // is large we want to force it down since we would prefer to
15455                    // keep launcher over it.
15456                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15457                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15458                        app.serviceHighRam = true;
15459                        app.serviceb = true;
15460                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15461                    } else {
15462                        mNewNumAServiceProcs++;
15463                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15464                    }
15465                } else {
15466                    app.serviceHighRam = false;
15467                }
15468            }
15469            if (app.serviceb) {
15470                adj = ProcessList.SERVICE_B_ADJ;
15471            }
15472        }
15473
15474        app.curRawAdj = adj;
15475
15476        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15477        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15478        if (adj > app.maxAdj) {
15479            adj = app.maxAdj;
15480            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15481                schedGroup = Process.THREAD_GROUP_DEFAULT;
15482            }
15483        }
15484        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15485            app.keeping = true;
15486        }
15487
15488        // Do final modification to adj.  Everything we do between here and applying
15489        // the final setAdj must be done in this function, because we will also use
15490        // it when computing the final cached adj later.  Note that we don't need to
15491        // worry about this for max adj above, since max adj will always be used to
15492        // keep it out of the cached vaues.
15493        app.curAdj = app.modifyRawOomAdj(adj);
15494        app.curSchedGroup = schedGroup;
15495        app.curProcState = procState;
15496        app.foregroundActivities = foregroundActivities;
15497
15498        return app.curRawAdj;
15499    }
15500
15501    /**
15502     * Schedule PSS collection of a process.
15503     */
15504    void requestPssLocked(ProcessRecord proc, int procState) {
15505        if (mPendingPssProcesses.contains(proc)) {
15506            return;
15507        }
15508        if (mPendingPssProcesses.size() == 0) {
15509            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15510        }
15511        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15512        proc.pssProcState = procState;
15513        mPendingPssProcesses.add(proc);
15514    }
15515
15516    /**
15517     * Schedule PSS collection of all processes.
15518     */
15519    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15520        if (!always) {
15521            if (now < (mLastFullPssTime +
15522                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15523                return;
15524            }
15525        }
15526        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15527        mLastFullPssTime = now;
15528        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15529        mPendingPssProcesses.clear();
15530        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15531            ProcessRecord app = mLruProcesses.get(i);
15532            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15533                app.pssProcState = app.setProcState;
15534                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15535                        isSleeping(), now);
15536                mPendingPssProcesses.add(app);
15537            }
15538        }
15539        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15540    }
15541
15542    /**
15543     * Ask a given process to GC right now.
15544     */
15545    final void performAppGcLocked(ProcessRecord app) {
15546        try {
15547            app.lastRequestedGc = SystemClock.uptimeMillis();
15548            if (app.thread != null) {
15549                if (app.reportLowMemory) {
15550                    app.reportLowMemory = false;
15551                    app.thread.scheduleLowMemory();
15552                } else {
15553                    app.thread.processInBackground();
15554                }
15555            }
15556        } catch (Exception e) {
15557            // whatever.
15558        }
15559    }
15560
15561    /**
15562     * Returns true if things are idle enough to perform GCs.
15563     */
15564    private final boolean canGcNowLocked() {
15565        boolean processingBroadcasts = false;
15566        for (BroadcastQueue q : mBroadcastQueues) {
15567            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15568                processingBroadcasts = true;
15569            }
15570        }
15571        return !processingBroadcasts
15572                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15573    }
15574
15575    /**
15576     * Perform GCs on all processes that are waiting for it, but only
15577     * if things are idle.
15578     */
15579    final void performAppGcsLocked() {
15580        final int N = mProcessesToGc.size();
15581        if (N <= 0) {
15582            return;
15583        }
15584        if (canGcNowLocked()) {
15585            while (mProcessesToGc.size() > 0) {
15586                ProcessRecord proc = mProcessesToGc.remove(0);
15587                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15588                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15589                            <= SystemClock.uptimeMillis()) {
15590                        // To avoid spamming the system, we will GC processes one
15591                        // at a time, waiting a few seconds between each.
15592                        performAppGcLocked(proc);
15593                        scheduleAppGcsLocked();
15594                        return;
15595                    } else {
15596                        // It hasn't been long enough since we last GCed this
15597                        // process...  put it in the list to wait for its time.
15598                        addProcessToGcListLocked(proc);
15599                        break;
15600                    }
15601                }
15602            }
15603
15604            scheduleAppGcsLocked();
15605        }
15606    }
15607
15608    /**
15609     * If all looks good, perform GCs on all processes waiting for them.
15610     */
15611    final void performAppGcsIfAppropriateLocked() {
15612        if (canGcNowLocked()) {
15613            performAppGcsLocked();
15614            return;
15615        }
15616        // Still not idle, wait some more.
15617        scheduleAppGcsLocked();
15618    }
15619
15620    /**
15621     * Schedule the execution of all pending app GCs.
15622     */
15623    final void scheduleAppGcsLocked() {
15624        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15625
15626        if (mProcessesToGc.size() > 0) {
15627            // Schedule a GC for the time to the next process.
15628            ProcessRecord proc = mProcessesToGc.get(0);
15629            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15630
15631            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15632            long now = SystemClock.uptimeMillis();
15633            if (when < (now+GC_TIMEOUT)) {
15634                when = now + GC_TIMEOUT;
15635            }
15636            mHandler.sendMessageAtTime(msg, when);
15637        }
15638    }
15639
15640    /**
15641     * Add a process to the array of processes waiting to be GCed.  Keeps the
15642     * list in sorted order by the last GC time.  The process can't already be
15643     * on the list.
15644     */
15645    final void addProcessToGcListLocked(ProcessRecord proc) {
15646        boolean added = false;
15647        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15648            if (mProcessesToGc.get(i).lastRequestedGc <
15649                    proc.lastRequestedGc) {
15650                added = true;
15651                mProcessesToGc.add(i+1, proc);
15652                break;
15653            }
15654        }
15655        if (!added) {
15656            mProcessesToGc.add(0, proc);
15657        }
15658    }
15659
15660    /**
15661     * Set up to ask a process to GC itself.  This will either do it
15662     * immediately, or put it on the list of processes to gc the next
15663     * time things are idle.
15664     */
15665    final void scheduleAppGcLocked(ProcessRecord app) {
15666        long now = SystemClock.uptimeMillis();
15667        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15668            return;
15669        }
15670        if (!mProcessesToGc.contains(app)) {
15671            addProcessToGcListLocked(app);
15672            scheduleAppGcsLocked();
15673        }
15674    }
15675
15676    final void checkExcessivePowerUsageLocked(boolean doKills) {
15677        updateCpuStatsNow();
15678
15679        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15680        boolean doWakeKills = doKills;
15681        boolean doCpuKills = doKills;
15682        if (mLastPowerCheckRealtime == 0) {
15683            doWakeKills = false;
15684        }
15685        if (mLastPowerCheckUptime == 0) {
15686            doCpuKills = false;
15687        }
15688        if (stats.isScreenOn()) {
15689            doWakeKills = false;
15690        }
15691        final long curRealtime = SystemClock.elapsedRealtime();
15692        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15693        final long curUptime = SystemClock.uptimeMillis();
15694        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15695        mLastPowerCheckRealtime = curRealtime;
15696        mLastPowerCheckUptime = curUptime;
15697        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15698            doWakeKills = false;
15699        }
15700        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15701            doCpuKills = false;
15702        }
15703        int i = mLruProcesses.size();
15704        while (i > 0) {
15705            i--;
15706            ProcessRecord app = mLruProcesses.get(i);
15707            if (!app.keeping) {
15708                long wtime;
15709                synchronized (stats) {
15710                    wtime = stats.getProcessWakeTime(app.info.uid,
15711                            app.pid, curRealtime);
15712                }
15713                long wtimeUsed = wtime - app.lastWakeTime;
15714                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15715                if (DEBUG_POWER) {
15716                    StringBuilder sb = new StringBuilder(128);
15717                    sb.append("Wake for ");
15718                    app.toShortString(sb);
15719                    sb.append(": over ");
15720                    TimeUtils.formatDuration(realtimeSince, sb);
15721                    sb.append(" used ");
15722                    TimeUtils.formatDuration(wtimeUsed, sb);
15723                    sb.append(" (");
15724                    sb.append((wtimeUsed*100)/realtimeSince);
15725                    sb.append("%)");
15726                    Slog.i(TAG, sb.toString());
15727                    sb.setLength(0);
15728                    sb.append("CPU for ");
15729                    app.toShortString(sb);
15730                    sb.append(": over ");
15731                    TimeUtils.formatDuration(uptimeSince, sb);
15732                    sb.append(" used ");
15733                    TimeUtils.formatDuration(cputimeUsed, sb);
15734                    sb.append(" (");
15735                    sb.append((cputimeUsed*100)/uptimeSince);
15736                    sb.append("%)");
15737                    Slog.i(TAG, sb.toString());
15738                }
15739                // If a process has held a wake lock for more
15740                // than 50% of the time during this period,
15741                // that sounds bad.  Kill!
15742                if (doWakeKills && realtimeSince > 0
15743                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15744                    synchronized (stats) {
15745                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15746                                realtimeSince, wtimeUsed);
15747                    }
15748                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15749                            + " during " + realtimeSince);
15750                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15751                } else if (doCpuKills && uptimeSince > 0
15752                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15753                    synchronized (stats) {
15754                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15755                                uptimeSince, cputimeUsed);
15756                    }
15757                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15758                            + " during " + uptimeSince);
15759                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15760                } else {
15761                    app.lastWakeTime = wtime;
15762                    app.lastCpuTime = app.curCpuTime;
15763                }
15764            }
15765        }
15766    }
15767
15768    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15769            ProcessRecord TOP_APP, boolean doingAll, long now) {
15770        boolean success = true;
15771
15772        if (app.curRawAdj != app.setRawAdj) {
15773            if (wasKeeping && !app.keeping) {
15774                // This app is no longer something we want to keep.  Note
15775                // its current wake lock time to later know to kill it if
15776                // it is not behaving well.
15777                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15778                synchronized (stats) {
15779                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15780                            app.pid, SystemClock.elapsedRealtime());
15781                }
15782                app.lastCpuTime = app.curCpuTime;
15783            }
15784
15785            app.setRawAdj = app.curRawAdj;
15786        }
15787
15788        int changes = 0;
15789
15790        if (app.curAdj != app.setAdj) {
15791            ProcessList.setOomAdj(app.pid, app.curAdj);
15792            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15793                TAG, "Set " + app.pid + " " + app.processName +
15794                " adj " + app.curAdj + ": " + app.adjType);
15795            app.setAdj = app.curAdj;
15796        }
15797
15798        if (app.setSchedGroup != app.curSchedGroup) {
15799            app.setSchedGroup = app.curSchedGroup;
15800            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15801                    "Setting process group of " + app.processName
15802                    + " to " + app.curSchedGroup);
15803            if (app.waitingToKill != null &&
15804                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15805                killUnneededProcessLocked(app, app.waitingToKill);
15806                success = false;
15807            } else {
15808                if (true) {
15809                    long oldId = Binder.clearCallingIdentity();
15810                    try {
15811                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15812                    } catch (Exception e) {
15813                        Slog.w(TAG, "Failed setting process group of " + app.pid
15814                                + " to " + app.curSchedGroup);
15815                        e.printStackTrace();
15816                    } finally {
15817                        Binder.restoreCallingIdentity(oldId);
15818                    }
15819                } else {
15820                    if (app.thread != null) {
15821                        try {
15822                            app.thread.setSchedulingGroup(app.curSchedGroup);
15823                        } catch (RemoteException e) {
15824                        }
15825                    }
15826                }
15827                Process.setSwappiness(app.pid,
15828                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15829            }
15830        }
15831        if (app.repForegroundActivities != app.foregroundActivities) {
15832            app.repForegroundActivities = app.foregroundActivities;
15833            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15834        }
15835        if (app.repProcState != app.curProcState) {
15836            app.repProcState = app.curProcState;
15837            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15838            if (app.thread != null) {
15839                try {
15840                    if (false) {
15841                        //RuntimeException h = new RuntimeException("here");
15842                        Slog.i(TAG, "Sending new process state " + app.repProcState
15843                                + " to " + app /*, h*/);
15844                    }
15845                    app.thread.setProcessState(app.repProcState);
15846                } catch (RemoteException e) {
15847                }
15848            }
15849        }
15850        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15851                app.setProcState)) {
15852            app.lastStateTime = now;
15853            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15854                    isSleeping(), now);
15855            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15856                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15857                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15858                    + (app.nextPssTime-now) + ": " + app);
15859        } else {
15860            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15861                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15862                requestPssLocked(app, app.setProcState);
15863                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15864                        isSleeping(), now);
15865            } else if (false && DEBUG_PSS) {
15866                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15867            }
15868        }
15869        if (app.setProcState != app.curProcState) {
15870            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15871                    "Proc state change of " + app.processName
15872                    + " to " + app.curProcState);
15873            app.setProcState = app.curProcState;
15874            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15875                app.notCachedSinceIdle = false;
15876            }
15877            if (!doingAll) {
15878                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15879            } else {
15880                app.procStateChanged = true;
15881            }
15882        }
15883
15884        if (changes != 0) {
15885            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15886            int i = mPendingProcessChanges.size()-1;
15887            ProcessChangeItem item = null;
15888            while (i >= 0) {
15889                item = mPendingProcessChanges.get(i);
15890                if (item.pid == app.pid) {
15891                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15892                    break;
15893                }
15894                i--;
15895            }
15896            if (i < 0) {
15897                // No existing item in pending changes; need a new one.
15898                final int NA = mAvailProcessChanges.size();
15899                if (NA > 0) {
15900                    item = mAvailProcessChanges.remove(NA-1);
15901                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15902                } else {
15903                    item = new ProcessChangeItem();
15904                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15905                }
15906                item.changes = 0;
15907                item.pid = app.pid;
15908                item.uid = app.info.uid;
15909                if (mPendingProcessChanges.size() == 0) {
15910                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15911                            "*** Enqueueing dispatch processes changed!");
15912                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15913                }
15914                mPendingProcessChanges.add(item);
15915            }
15916            item.changes |= changes;
15917            item.processState = app.repProcState;
15918            item.foregroundActivities = app.repForegroundActivities;
15919            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15920                    + Integer.toHexString(System.identityHashCode(item))
15921                    + " " + app.toShortString() + ": changes=" + item.changes
15922                    + " procState=" + item.processState
15923                    + " foreground=" + item.foregroundActivities
15924                    + " type=" + app.adjType + " source=" + app.adjSource
15925                    + " target=" + app.adjTarget);
15926        }
15927
15928        return success;
15929    }
15930
15931    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15932        if (proc.thread != null && proc.baseProcessTracker != null) {
15933            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15934        }
15935    }
15936
15937    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15938            ProcessRecord TOP_APP, boolean doingAll, long now) {
15939        if (app.thread == null) {
15940            return false;
15941        }
15942
15943        final boolean wasKeeping = app.keeping;
15944
15945        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15946
15947        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15948    }
15949
15950    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15951            boolean oomAdj) {
15952        if (isForeground != proc.foregroundServices) {
15953            proc.foregroundServices = isForeground;
15954            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15955                    proc.info.uid);
15956            if (isForeground) {
15957                if (curProcs == null) {
15958                    curProcs = new ArrayList<ProcessRecord>();
15959                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15960                }
15961                if (!curProcs.contains(proc)) {
15962                    curProcs.add(proc);
15963                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15964                            proc.info.packageName, proc.info.uid);
15965                }
15966            } else {
15967                if (curProcs != null) {
15968                    if (curProcs.remove(proc)) {
15969                        mBatteryStatsService.noteEvent(
15970                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15971                                proc.info.packageName, proc.info.uid);
15972                        if (curProcs.size() <= 0) {
15973                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15974                        }
15975                    }
15976                }
15977            }
15978            if (oomAdj) {
15979                updateOomAdjLocked();
15980            }
15981        }
15982    }
15983
15984    private final ActivityRecord resumedAppLocked() {
15985        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15986        String pkg;
15987        int uid;
15988        if (act != null && !act.sleeping) {
15989            pkg = act.packageName;
15990            uid = act.info.applicationInfo.uid;
15991        } else {
15992            pkg = null;
15993            uid = -1;
15994        }
15995        // Has the UID or resumed package name changed?
15996        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15997                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15998            if (mCurResumedPackage != null) {
15999                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16000                        mCurResumedPackage, mCurResumedUid);
16001            }
16002            mCurResumedPackage = pkg;
16003            mCurResumedUid = uid;
16004            if (mCurResumedPackage != null) {
16005                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16006                        mCurResumedPackage, mCurResumedUid);
16007            }
16008        }
16009        return act;
16010    }
16011
16012    final boolean updateOomAdjLocked(ProcessRecord app) {
16013        final ActivityRecord TOP_ACT = resumedAppLocked();
16014        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16015        final boolean wasCached = app.cached;
16016
16017        mAdjSeq++;
16018
16019        // This is the desired cached adjusment we want to tell it to use.
16020        // If our app is currently cached, we know it, and that is it.  Otherwise,
16021        // we don't know it yet, and it needs to now be cached we will then
16022        // need to do a complete oom adj.
16023        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16024                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16025        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16026                SystemClock.uptimeMillis());
16027        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16028            // Changed to/from cached state, so apps after it in the LRU
16029            // list may also be changed.
16030            updateOomAdjLocked();
16031        }
16032        return success;
16033    }
16034
16035    final void updateOomAdjLocked() {
16036        final ActivityRecord TOP_ACT = resumedAppLocked();
16037        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16038        final long now = SystemClock.uptimeMillis();
16039        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16040        final int N = mLruProcesses.size();
16041
16042        if (false) {
16043            RuntimeException e = new RuntimeException();
16044            e.fillInStackTrace();
16045            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16046        }
16047
16048        mAdjSeq++;
16049        mNewNumServiceProcs = 0;
16050        mNewNumAServiceProcs = 0;
16051
16052        final int emptyProcessLimit;
16053        final int cachedProcessLimit;
16054        if (mProcessLimit <= 0) {
16055            emptyProcessLimit = cachedProcessLimit = 0;
16056        } else if (mProcessLimit == 1) {
16057            emptyProcessLimit = 1;
16058            cachedProcessLimit = 0;
16059        } else {
16060            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16061            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16062        }
16063
16064        // Let's determine how many processes we have running vs.
16065        // how many slots we have for background processes; we may want
16066        // to put multiple processes in a slot of there are enough of
16067        // them.
16068        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16069                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16070        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16071        if (numEmptyProcs > cachedProcessLimit) {
16072            // If there are more empty processes than our limit on cached
16073            // processes, then use the cached process limit for the factor.
16074            // This ensures that the really old empty processes get pushed
16075            // down to the bottom, so if we are running low on memory we will
16076            // have a better chance at keeping around more cached processes
16077            // instead of a gazillion empty processes.
16078            numEmptyProcs = cachedProcessLimit;
16079        }
16080        int emptyFactor = numEmptyProcs/numSlots;
16081        if (emptyFactor < 1) emptyFactor = 1;
16082        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16083        if (cachedFactor < 1) cachedFactor = 1;
16084        int stepCached = 0;
16085        int stepEmpty = 0;
16086        int numCached = 0;
16087        int numEmpty = 0;
16088        int numTrimming = 0;
16089
16090        mNumNonCachedProcs = 0;
16091        mNumCachedHiddenProcs = 0;
16092
16093        // First update the OOM adjustment for each of the
16094        // application processes based on their current state.
16095        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16096        int nextCachedAdj = curCachedAdj+1;
16097        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16098        int nextEmptyAdj = curEmptyAdj+2;
16099        for (int i=N-1; i>=0; i--) {
16100            ProcessRecord app = mLruProcesses.get(i);
16101            if (!app.killedByAm && app.thread != null) {
16102                app.procStateChanged = false;
16103                final boolean wasKeeping = app.keeping;
16104                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16105
16106                // If we haven't yet assigned the final cached adj
16107                // to the process, do that now.
16108                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16109                    switch (app.curProcState) {
16110                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16111                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16112                            // This process is a cached process holding activities...
16113                            // assign it the next cached value for that type, and then
16114                            // step that cached level.
16115                            app.curRawAdj = curCachedAdj;
16116                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16117                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16118                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16119                                    + ")");
16120                            if (curCachedAdj != nextCachedAdj) {
16121                                stepCached++;
16122                                if (stepCached >= cachedFactor) {
16123                                    stepCached = 0;
16124                                    curCachedAdj = nextCachedAdj;
16125                                    nextCachedAdj += 2;
16126                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16127                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16128                                    }
16129                                }
16130                            }
16131                            break;
16132                        default:
16133                            // For everything else, assign next empty cached process
16134                            // level and bump that up.  Note that this means that
16135                            // long-running services that have dropped down to the
16136                            // cached level will be treated as empty (since their process
16137                            // state is still as a service), which is what we want.
16138                            app.curRawAdj = curEmptyAdj;
16139                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16140                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16141                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16142                                    + ")");
16143                            if (curEmptyAdj != nextEmptyAdj) {
16144                                stepEmpty++;
16145                                if (stepEmpty >= emptyFactor) {
16146                                    stepEmpty = 0;
16147                                    curEmptyAdj = nextEmptyAdj;
16148                                    nextEmptyAdj += 2;
16149                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16150                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16151                                    }
16152                                }
16153                            }
16154                            break;
16155                    }
16156                }
16157
16158                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16159
16160                // Count the number of process types.
16161                switch (app.curProcState) {
16162                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16163                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16164                        mNumCachedHiddenProcs++;
16165                        numCached++;
16166                        if (numCached > cachedProcessLimit) {
16167                            killUnneededProcessLocked(app, "cached #" + numCached);
16168                        }
16169                        break;
16170                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16171                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16172                                && app.lastActivityTime < oldTime) {
16173                            killUnneededProcessLocked(app, "empty for "
16174                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16175                                    / 1000) + "s");
16176                        } else {
16177                            numEmpty++;
16178                            if (numEmpty > emptyProcessLimit) {
16179                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16180                            }
16181                        }
16182                        break;
16183                    default:
16184                        mNumNonCachedProcs++;
16185                        break;
16186                }
16187
16188                if (app.isolated && app.services.size() <= 0) {
16189                    // If this is an isolated process, and there are no
16190                    // services running in it, then the process is no longer
16191                    // needed.  We agressively kill these because we can by
16192                    // definition not re-use the same process again, and it is
16193                    // good to avoid having whatever code was running in them
16194                    // left sitting around after no longer needed.
16195                    killUnneededProcessLocked(app, "isolated not needed");
16196                }
16197
16198                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16199                        && !app.killedByAm) {
16200                    numTrimming++;
16201                }
16202            }
16203        }
16204
16205        mNumServiceProcs = mNewNumServiceProcs;
16206
16207        // Now determine the memory trimming level of background processes.
16208        // Unfortunately we need to start at the back of the list to do this
16209        // properly.  We only do this if the number of background apps we
16210        // are managing to keep around is less than half the maximum we desire;
16211        // if we are keeping a good number around, we'll let them use whatever
16212        // memory they want.
16213        final int numCachedAndEmpty = numCached + numEmpty;
16214        int memFactor;
16215        if (numCached <= ProcessList.TRIM_CACHED_APPS
16216                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16217            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16218                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16219            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16220                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16221            } else {
16222                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16223            }
16224        } else {
16225            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16226        }
16227        // We always allow the memory level to go up (better).  We only allow it to go
16228        // down if we are in a state where that is allowed, *and* the total number of processes
16229        // has gone down since last time.
16230        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16231                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16232                + " last=" + mLastNumProcesses);
16233        if (memFactor > mLastMemoryLevel) {
16234            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16235                memFactor = mLastMemoryLevel;
16236                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16237            }
16238        }
16239        mLastMemoryLevel = memFactor;
16240        mLastNumProcesses = mLruProcesses.size();
16241        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16242        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16243        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16244            if (mLowRamStartTime == 0) {
16245                mLowRamStartTime = now;
16246            }
16247            int step = 0;
16248            int fgTrimLevel;
16249            switch (memFactor) {
16250                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16251                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16252                    break;
16253                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16254                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16255                    break;
16256                default:
16257                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16258                    break;
16259            }
16260            int factor = numTrimming/3;
16261            int minFactor = 2;
16262            if (mHomeProcess != null) minFactor++;
16263            if (mPreviousProcess != null) minFactor++;
16264            if (factor < minFactor) factor = minFactor;
16265            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16266            for (int i=N-1; i>=0; i--) {
16267                ProcessRecord app = mLruProcesses.get(i);
16268                if (allChanged || app.procStateChanged) {
16269                    setProcessTrackerState(app, trackerMemFactor, now);
16270                    app.procStateChanged = false;
16271                }
16272                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16273                        && !app.killedByAm) {
16274                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16275                        try {
16276                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16277                                    "Trimming memory of " + app.processName
16278                                    + " to " + curLevel);
16279                            app.thread.scheduleTrimMemory(curLevel);
16280                        } catch (RemoteException e) {
16281                        }
16282                        if (false) {
16283                            // For now we won't do this; our memory trimming seems
16284                            // to be good enough at this point that destroying
16285                            // activities causes more harm than good.
16286                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16287                                    && app != mHomeProcess && app != mPreviousProcess) {
16288                                // Need to do this on its own message because the stack may not
16289                                // be in a consistent state at this point.
16290                                // For these apps we will also finish their activities
16291                                // to help them free memory.
16292                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16293                            }
16294                        }
16295                    }
16296                    app.trimMemoryLevel = curLevel;
16297                    step++;
16298                    if (step >= factor) {
16299                        step = 0;
16300                        switch (curLevel) {
16301                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16302                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16303                                break;
16304                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16305                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16306                                break;
16307                        }
16308                    }
16309                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16310                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16311                            && app.thread != null) {
16312                        try {
16313                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16314                                    "Trimming memory of heavy-weight " + app.processName
16315                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16316                            app.thread.scheduleTrimMemory(
16317                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16318                        } catch (RemoteException e) {
16319                        }
16320                    }
16321                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16322                } else {
16323                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16324                            || app.systemNoUi) && app.pendingUiClean) {
16325                        // If this application is now in the background and it
16326                        // had done UI, then give it the special trim level to
16327                        // have it free UI resources.
16328                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16329                        if (app.trimMemoryLevel < level && app.thread != null) {
16330                            try {
16331                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16332                                        "Trimming memory of bg-ui " + app.processName
16333                                        + " to " + level);
16334                                app.thread.scheduleTrimMemory(level);
16335                            } catch (RemoteException e) {
16336                            }
16337                        }
16338                        app.pendingUiClean = false;
16339                    }
16340                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16341                        try {
16342                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16343                                    "Trimming memory of fg " + app.processName
16344                                    + " to " + fgTrimLevel);
16345                            app.thread.scheduleTrimMemory(fgTrimLevel);
16346                        } catch (RemoteException e) {
16347                        }
16348                    }
16349                    app.trimMemoryLevel = fgTrimLevel;
16350                }
16351            }
16352        } else {
16353            if (mLowRamStartTime != 0) {
16354                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16355                mLowRamStartTime = 0;
16356            }
16357            for (int i=N-1; i>=0; i--) {
16358                ProcessRecord app = mLruProcesses.get(i);
16359                if (allChanged || app.procStateChanged) {
16360                    setProcessTrackerState(app, trackerMemFactor, now);
16361                    app.procStateChanged = false;
16362                }
16363                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16364                        || app.systemNoUi) && app.pendingUiClean) {
16365                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16366                            && app.thread != null) {
16367                        try {
16368                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16369                                    "Trimming memory of ui hidden " + app.processName
16370                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16371                            app.thread.scheduleTrimMemory(
16372                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16373                        } catch (RemoteException e) {
16374                        }
16375                    }
16376                    app.pendingUiClean = false;
16377                }
16378                app.trimMemoryLevel = 0;
16379            }
16380        }
16381
16382        if (mAlwaysFinishActivities) {
16383            // Need to do this on its own message because the stack may not
16384            // be in a consistent state at this point.
16385            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16386        }
16387
16388        if (allChanged) {
16389            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16390        }
16391
16392        if (mProcessStats.shouldWriteNowLocked(now)) {
16393            mHandler.post(new Runnable() {
16394                @Override public void run() {
16395                    synchronized (ActivityManagerService.this) {
16396                        mProcessStats.writeStateAsyncLocked();
16397                    }
16398                }
16399            });
16400        }
16401
16402        if (DEBUG_OOM_ADJ) {
16403            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16404        }
16405    }
16406
16407    final void trimApplications() {
16408        synchronized (this) {
16409            int i;
16410
16411            // First remove any unused application processes whose package
16412            // has been removed.
16413            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16414                final ProcessRecord app = mRemovedProcesses.get(i);
16415                if (app.activities.size() == 0
16416                        && app.curReceiver == null && app.services.size() == 0) {
16417                    Slog.i(
16418                        TAG, "Exiting empty application process "
16419                        + app.processName + " ("
16420                        + (app.thread != null ? app.thread.asBinder() : null)
16421                        + ")\n");
16422                    if (app.pid > 0 && app.pid != MY_PID) {
16423                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16424                                app.processName, app.setAdj, "empty");
16425                        app.killedByAm = true;
16426                        Process.killProcessQuiet(app.pid);
16427                    } else {
16428                        try {
16429                            app.thread.scheduleExit();
16430                        } catch (Exception e) {
16431                            // Ignore exceptions.
16432                        }
16433                    }
16434                    cleanUpApplicationRecordLocked(app, false, true, -1);
16435                    mRemovedProcesses.remove(i);
16436
16437                    if (app.persistent) {
16438                        if (app.persistent) {
16439                            addAppLocked(app.info, false, null /* ABI override */);
16440                        }
16441                    }
16442                }
16443            }
16444
16445            // Now update the oom adj for all processes.
16446            updateOomAdjLocked();
16447        }
16448    }
16449
16450    /** This method sends the specified signal to each of the persistent apps */
16451    public void signalPersistentProcesses(int sig) throws RemoteException {
16452        if (sig != Process.SIGNAL_USR1) {
16453            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16454        }
16455
16456        synchronized (this) {
16457            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16458                    != PackageManager.PERMISSION_GRANTED) {
16459                throw new SecurityException("Requires permission "
16460                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16461            }
16462
16463            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16464                ProcessRecord r = mLruProcesses.get(i);
16465                if (r.thread != null && r.persistent) {
16466                    Process.sendSignal(r.pid, sig);
16467                }
16468            }
16469        }
16470    }
16471
16472    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16473        if (proc == null || proc == mProfileProc) {
16474            proc = mProfileProc;
16475            path = mProfileFile;
16476            profileType = mProfileType;
16477            clearProfilerLocked();
16478        }
16479        if (proc == null) {
16480            return;
16481        }
16482        try {
16483            proc.thread.profilerControl(false, path, null, profileType);
16484        } catch (RemoteException e) {
16485            throw new IllegalStateException("Process disappeared");
16486        }
16487    }
16488
16489    private void clearProfilerLocked() {
16490        if (mProfileFd != null) {
16491            try {
16492                mProfileFd.close();
16493            } catch (IOException e) {
16494            }
16495        }
16496        mProfileApp = null;
16497        mProfileProc = null;
16498        mProfileFile = null;
16499        mProfileType = 0;
16500        mAutoStopProfiler = false;
16501    }
16502
16503    public boolean profileControl(String process, int userId, boolean start,
16504            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16505
16506        try {
16507            synchronized (this) {
16508                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16509                // its own permission.
16510                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16511                        != PackageManager.PERMISSION_GRANTED) {
16512                    throw new SecurityException("Requires permission "
16513                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16514                }
16515
16516                if (start && fd == null) {
16517                    throw new IllegalArgumentException("null fd");
16518                }
16519
16520                ProcessRecord proc = null;
16521                if (process != null) {
16522                    proc = findProcessLocked(process, userId, "profileControl");
16523                }
16524
16525                if (start && (proc == null || proc.thread == null)) {
16526                    throw new IllegalArgumentException("Unknown process: " + process);
16527                }
16528
16529                if (start) {
16530                    stopProfilerLocked(null, null, 0);
16531                    setProfileApp(proc.info, proc.processName, path, fd, false);
16532                    mProfileProc = proc;
16533                    mProfileType = profileType;
16534                    try {
16535                        fd = fd.dup();
16536                    } catch (IOException e) {
16537                        fd = null;
16538                    }
16539                    proc.thread.profilerControl(start, path, fd, profileType);
16540                    fd = null;
16541                    mProfileFd = null;
16542                } else {
16543                    stopProfilerLocked(proc, path, profileType);
16544                    if (fd != null) {
16545                        try {
16546                            fd.close();
16547                        } catch (IOException e) {
16548                        }
16549                    }
16550                }
16551
16552                return true;
16553            }
16554        } catch (RemoteException e) {
16555            throw new IllegalStateException("Process disappeared");
16556        } finally {
16557            if (fd != null) {
16558                try {
16559                    fd.close();
16560                } catch (IOException e) {
16561                }
16562            }
16563        }
16564    }
16565
16566    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16567        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16568                userId, true, true, callName, null);
16569        ProcessRecord proc = null;
16570        try {
16571            int pid = Integer.parseInt(process);
16572            synchronized (mPidsSelfLocked) {
16573                proc = mPidsSelfLocked.get(pid);
16574            }
16575        } catch (NumberFormatException e) {
16576        }
16577
16578        if (proc == null) {
16579            ArrayMap<String, SparseArray<ProcessRecord>> all
16580                    = mProcessNames.getMap();
16581            SparseArray<ProcessRecord> procs = all.get(process);
16582            if (procs != null && procs.size() > 0) {
16583                proc = procs.valueAt(0);
16584                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16585                    for (int i=1; i<procs.size(); i++) {
16586                        ProcessRecord thisProc = procs.valueAt(i);
16587                        if (thisProc.userId == userId) {
16588                            proc = thisProc;
16589                            break;
16590                        }
16591                    }
16592                }
16593            }
16594        }
16595
16596        return proc;
16597    }
16598
16599    public boolean dumpHeap(String process, int userId, boolean managed,
16600            String path, ParcelFileDescriptor fd) throws RemoteException {
16601
16602        try {
16603            synchronized (this) {
16604                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16605                // its own permission (same as profileControl).
16606                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16607                        != PackageManager.PERMISSION_GRANTED) {
16608                    throw new SecurityException("Requires permission "
16609                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16610                }
16611
16612                if (fd == null) {
16613                    throw new IllegalArgumentException("null fd");
16614                }
16615
16616                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16617                if (proc == null || proc.thread == null) {
16618                    throw new IllegalArgumentException("Unknown process: " + process);
16619                }
16620
16621                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16622                if (!isDebuggable) {
16623                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16624                        throw new SecurityException("Process not debuggable: " + proc);
16625                    }
16626                }
16627
16628                proc.thread.dumpHeap(managed, path, fd);
16629                fd = null;
16630                return true;
16631            }
16632        } catch (RemoteException e) {
16633            throw new IllegalStateException("Process disappeared");
16634        } finally {
16635            if (fd != null) {
16636                try {
16637                    fd.close();
16638                } catch (IOException e) {
16639                }
16640            }
16641        }
16642    }
16643
16644    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16645    public void monitor() {
16646        synchronized (this) { }
16647    }
16648
16649    void onCoreSettingsChange(Bundle settings) {
16650        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16651            ProcessRecord processRecord = mLruProcesses.get(i);
16652            try {
16653                if (processRecord.thread != null) {
16654                    processRecord.thread.setCoreSettings(settings);
16655                }
16656            } catch (RemoteException re) {
16657                /* ignore */
16658            }
16659        }
16660    }
16661
16662    // Multi-user methods
16663
16664    /**
16665     * Start user, if its not already running, but don't bring it to foreground.
16666     */
16667    @Override
16668    public boolean startUserInBackground(final int userId) {
16669        return startUser(userId, /* foreground */ false);
16670    }
16671
16672    /**
16673     * Refreshes the list of users related to the current user when either a
16674     * user switch happens or when a new related user is started in the
16675     * background.
16676     */
16677    private void updateCurrentProfileIdsLocked() {
16678        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16679                mCurrentUserId, false /* enabledOnly */);
16680        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16681        for (int i = 0; i < currentProfileIds.length; i++) {
16682            currentProfileIds[i] = profiles.get(i).id;
16683        }
16684        mCurrentProfileIds = currentProfileIds;
16685    }
16686
16687    private Set getProfileIdsLocked(int userId) {
16688        Set userIds = new HashSet<Integer>();
16689        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16690                userId, false /* enabledOnly */);
16691        for (UserInfo user : profiles) {
16692            userIds.add(Integer.valueOf(user.id));
16693        }
16694        return userIds;
16695    }
16696
16697    @Override
16698    public boolean switchUser(final int userId) {
16699        return startUser(userId, /* foregound */ true);
16700    }
16701
16702    private boolean startUser(final int userId, boolean foreground) {
16703        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16704                != PackageManager.PERMISSION_GRANTED) {
16705            String msg = "Permission Denial: switchUser() from pid="
16706                    + Binder.getCallingPid()
16707                    + ", uid=" + Binder.getCallingUid()
16708                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16709            Slog.w(TAG, msg);
16710            throw new SecurityException(msg);
16711        }
16712
16713        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16714
16715        final long ident = Binder.clearCallingIdentity();
16716        try {
16717            synchronized (this) {
16718                final int oldUserId = mCurrentUserId;
16719                if (oldUserId == userId) {
16720                    return true;
16721                }
16722
16723                mStackSupervisor.setLockTaskModeLocked(null, false);
16724
16725                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16726                if (userInfo == null) {
16727                    Slog.w(TAG, "No user info for user #" + userId);
16728                    return false;
16729                }
16730
16731                if (foreground) {
16732                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16733                            R.anim.screen_user_enter);
16734                }
16735
16736                boolean needStart = false;
16737
16738                // If the user we are switching to is not currently started, then
16739                // we need to start it now.
16740                if (mStartedUsers.get(userId) == null) {
16741                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16742                    updateStartedUserArrayLocked();
16743                    needStart = true;
16744                }
16745
16746                final Integer userIdInt = Integer.valueOf(userId);
16747                mUserLru.remove(userIdInt);
16748                mUserLru.add(userIdInt);
16749
16750                if (foreground) {
16751                    mCurrentUserId = userId;
16752                    updateCurrentProfileIdsLocked();
16753                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16754                    // Once the internal notion of the active user has switched, we lock the device
16755                    // with the option to show the user switcher on the keyguard.
16756                    mWindowManager.lockNow(null);
16757                } else {
16758                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16759                    updateCurrentProfileIdsLocked();
16760                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16761                    mUserLru.remove(currentUserIdInt);
16762                    mUserLru.add(currentUserIdInt);
16763                }
16764
16765                final UserStartedState uss = mStartedUsers.get(userId);
16766
16767                // Make sure user is in the started state.  If it is currently
16768                // stopping, we need to knock that off.
16769                if (uss.mState == UserStartedState.STATE_STOPPING) {
16770                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16771                    // so we can just fairly silently bring the user back from
16772                    // the almost-dead.
16773                    uss.mState = UserStartedState.STATE_RUNNING;
16774                    updateStartedUserArrayLocked();
16775                    needStart = true;
16776                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16777                    // This means ACTION_SHUTDOWN has been sent, so we will
16778                    // need to treat this as a new boot of the user.
16779                    uss.mState = UserStartedState.STATE_BOOTING;
16780                    updateStartedUserArrayLocked();
16781                    needStart = true;
16782                }
16783
16784                if (uss.mState == UserStartedState.STATE_BOOTING) {
16785                    // Booting up a new user, need to tell system services about it.
16786                    // Note that this is on the same handler as scheduling of broadcasts,
16787                    // which is important because it needs to go first.
16788                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16789                }
16790
16791                if (foreground) {
16792                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16793                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16794                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16795                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16796                            oldUserId, userId, uss));
16797                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16798                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16799                }
16800
16801                if (needStart) {
16802                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16803                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16804                            | Intent.FLAG_RECEIVER_FOREGROUND);
16805                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16806                    broadcastIntentLocked(null, null, intent,
16807                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16808                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16809                }
16810
16811                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16812                    if (userId != UserHandle.USER_OWNER) {
16813                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16814                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16815                        broadcastIntentLocked(null, null, intent, null,
16816                                new IIntentReceiver.Stub() {
16817                                    public void performReceive(Intent intent, int resultCode,
16818                                            String data, Bundle extras, boolean ordered,
16819                                            boolean sticky, int sendingUser) {
16820                                        userInitialized(uss, userId);
16821                                    }
16822                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16823                                true, false, MY_PID, Process.SYSTEM_UID,
16824                                userId);
16825                        uss.initializing = true;
16826                    } else {
16827                        getUserManagerLocked().makeInitialized(userInfo.id);
16828                    }
16829                }
16830
16831                if (foreground) {
16832                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16833                    if (homeInFront) {
16834                        startHomeActivityLocked(userId);
16835                    } else {
16836                        mStackSupervisor.resumeTopActivitiesLocked();
16837                    }
16838                    EventLogTags.writeAmSwitchUser(userId);
16839                    getUserManagerLocked().userForeground(userId);
16840                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16841                } else {
16842                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16843                }
16844
16845                if (needStart) {
16846                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16847                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16848                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16849                    broadcastIntentLocked(null, null, intent,
16850                            null, new IIntentReceiver.Stub() {
16851                                @Override
16852                                public void performReceive(Intent intent, int resultCode, String data,
16853                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16854                                        throws RemoteException {
16855                                }
16856                            }, 0, null, null,
16857                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16858                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16859                }
16860            }
16861        } finally {
16862            Binder.restoreCallingIdentity(ident);
16863        }
16864
16865        return true;
16866    }
16867
16868    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16869        long ident = Binder.clearCallingIdentity();
16870        try {
16871            Intent intent;
16872            if (oldUserId >= 0) {
16873                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16874                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16875                        | Intent.FLAG_RECEIVER_FOREGROUND);
16876                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16877                broadcastIntentLocked(null, null, intent,
16878                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16879                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16880            }
16881            if (newUserId >= 0) {
16882                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16883                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16884                        | Intent.FLAG_RECEIVER_FOREGROUND);
16885                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16886                broadcastIntentLocked(null, null, intent,
16887                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16888                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16889                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16890                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16891                        | Intent.FLAG_RECEIVER_FOREGROUND);
16892                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16893                broadcastIntentLocked(null, null, intent,
16894                        null, null, 0, null, null,
16895                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16896                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16897            }
16898        } finally {
16899            Binder.restoreCallingIdentity(ident);
16900        }
16901    }
16902
16903    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16904            final int newUserId) {
16905        final int N = mUserSwitchObservers.beginBroadcast();
16906        if (N > 0) {
16907            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16908                int mCount = 0;
16909                @Override
16910                public void sendResult(Bundle data) throws RemoteException {
16911                    synchronized (ActivityManagerService.this) {
16912                        if (mCurUserSwitchCallback == this) {
16913                            mCount++;
16914                            if (mCount == N) {
16915                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16916                            }
16917                        }
16918                    }
16919                }
16920            };
16921            synchronized (this) {
16922                uss.switching = true;
16923                mCurUserSwitchCallback = callback;
16924            }
16925            for (int i=0; i<N; i++) {
16926                try {
16927                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16928                            newUserId, callback);
16929                } catch (RemoteException e) {
16930                }
16931            }
16932        } else {
16933            synchronized (this) {
16934                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16935            }
16936        }
16937        mUserSwitchObservers.finishBroadcast();
16938    }
16939
16940    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16941        synchronized (this) {
16942            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16943            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16944        }
16945    }
16946
16947    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16948        mCurUserSwitchCallback = null;
16949        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16950        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16951                oldUserId, newUserId, uss));
16952    }
16953
16954    void userInitialized(UserStartedState uss, int newUserId) {
16955        completeSwitchAndInitalize(uss, newUserId, true, false);
16956    }
16957
16958    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16959        completeSwitchAndInitalize(uss, newUserId, false, true);
16960    }
16961
16962    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16963            boolean clearInitializing, boolean clearSwitching) {
16964        boolean unfrozen = false;
16965        synchronized (this) {
16966            if (clearInitializing) {
16967                uss.initializing = false;
16968                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16969            }
16970            if (clearSwitching) {
16971                uss.switching = false;
16972            }
16973            if (!uss.switching && !uss.initializing) {
16974                mWindowManager.stopFreezingScreen();
16975                unfrozen = true;
16976            }
16977        }
16978        if (unfrozen) {
16979            final int N = mUserSwitchObservers.beginBroadcast();
16980            for (int i=0; i<N; i++) {
16981                try {
16982                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16983                } catch (RemoteException e) {
16984                }
16985            }
16986            mUserSwitchObservers.finishBroadcast();
16987        }
16988    }
16989
16990    void scheduleStartProfilesLocked() {
16991        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16992            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16993                    DateUtils.SECOND_IN_MILLIS);
16994        }
16995    }
16996
16997    void startProfilesLocked() {
16998        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16999        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17000                mCurrentUserId, false /* enabledOnly */);
17001        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17002        for (UserInfo user : profiles) {
17003            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17004                    && user.id != mCurrentUserId) {
17005                toStart.add(user);
17006            }
17007        }
17008        final int n = toStart.size();
17009        int i = 0;
17010        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17011            startUserInBackground(toStart.get(i).id);
17012        }
17013        if (i < n) {
17014            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17015        }
17016    }
17017
17018    void finishUserBoot(UserStartedState uss) {
17019        synchronized (this) {
17020            if (uss.mState == UserStartedState.STATE_BOOTING
17021                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17022                uss.mState = UserStartedState.STATE_RUNNING;
17023                final int userId = uss.mHandle.getIdentifier();
17024                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17025                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17026                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17027                broadcastIntentLocked(null, null, intent,
17028                        null, null, 0, null, null,
17029                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17030                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17031            }
17032        }
17033    }
17034
17035    void finishUserSwitch(UserStartedState uss) {
17036        synchronized (this) {
17037            finishUserBoot(uss);
17038
17039            startProfilesLocked();
17040
17041            int num = mUserLru.size();
17042            int i = 0;
17043            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17044                Integer oldUserId = mUserLru.get(i);
17045                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17046                if (oldUss == null) {
17047                    // Shouldn't happen, but be sane if it does.
17048                    mUserLru.remove(i);
17049                    num--;
17050                    continue;
17051                }
17052                if (oldUss.mState == UserStartedState.STATE_STOPPING
17053                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17054                    // This user is already stopping, doesn't count.
17055                    num--;
17056                    i++;
17057                    continue;
17058                }
17059                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17060                    // Owner and current can't be stopped, but count as running.
17061                    i++;
17062                    continue;
17063                }
17064                // This is a user to be stopped.
17065                stopUserLocked(oldUserId, null);
17066                num--;
17067                i++;
17068            }
17069        }
17070    }
17071
17072    @Override
17073    public int stopUser(final int userId, final IStopUserCallback callback) {
17074        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17075                != PackageManager.PERMISSION_GRANTED) {
17076            String msg = "Permission Denial: switchUser() from pid="
17077                    + Binder.getCallingPid()
17078                    + ", uid=" + Binder.getCallingUid()
17079                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17080            Slog.w(TAG, msg);
17081            throw new SecurityException(msg);
17082        }
17083        if (userId <= 0) {
17084            throw new IllegalArgumentException("Can't stop primary user " + userId);
17085        }
17086        synchronized (this) {
17087            return stopUserLocked(userId, callback);
17088        }
17089    }
17090
17091    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17092        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17093        if (mCurrentUserId == userId) {
17094            return ActivityManager.USER_OP_IS_CURRENT;
17095        }
17096
17097        final UserStartedState uss = mStartedUsers.get(userId);
17098        if (uss == null) {
17099            // User is not started, nothing to do...  but we do need to
17100            // callback if requested.
17101            if (callback != null) {
17102                mHandler.post(new Runnable() {
17103                    @Override
17104                    public void run() {
17105                        try {
17106                            callback.userStopped(userId);
17107                        } catch (RemoteException e) {
17108                        }
17109                    }
17110                });
17111            }
17112            return ActivityManager.USER_OP_SUCCESS;
17113        }
17114
17115        if (callback != null) {
17116            uss.mStopCallbacks.add(callback);
17117        }
17118
17119        if (uss.mState != UserStartedState.STATE_STOPPING
17120                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17121            uss.mState = UserStartedState.STATE_STOPPING;
17122            updateStartedUserArrayLocked();
17123
17124            long ident = Binder.clearCallingIdentity();
17125            try {
17126                // We are going to broadcast ACTION_USER_STOPPING and then
17127                // once that is done send a final ACTION_SHUTDOWN and then
17128                // stop the user.
17129                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17130                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17131                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17132                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17133                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17134                // This is the result receiver for the final shutdown broadcast.
17135                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17136                    @Override
17137                    public void performReceive(Intent intent, int resultCode, String data,
17138                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17139                        finishUserStop(uss);
17140                    }
17141                };
17142                // This is the result receiver for the initial stopping broadcast.
17143                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17144                    @Override
17145                    public void performReceive(Intent intent, int resultCode, String data,
17146                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17147                        // On to the next.
17148                        synchronized (ActivityManagerService.this) {
17149                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17150                                // Whoops, we are being started back up.  Abort, abort!
17151                                return;
17152                            }
17153                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17154                        }
17155                        mSystemServiceManager.stopUser(userId);
17156                        broadcastIntentLocked(null, null, shutdownIntent,
17157                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17158                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17159                    }
17160                };
17161                // Kick things off.
17162                broadcastIntentLocked(null, null, stoppingIntent,
17163                        null, stoppingReceiver, 0, null, null,
17164                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17165                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17166            } finally {
17167                Binder.restoreCallingIdentity(ident);
17168            }
17169        }
17170
17171        return ActivityManager.USER_OP_SUCCESS;
17172    }
17173
17174    void finishUserStop(UserStartedState uss) {
17175        final int userId = uss.mHandle.getIdentifier();
17176        boolean stopped;
17177        ArrayList<IStopUserCallback> callbacks;
17178        synchronized (this) {
17179            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17180            if (mStartedUsers.get(userId) != uss) {
17181                stopped = false;
17182            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17183                stopped = false;
17184            } else {
17185                stopped = true;
17186                // User can no longer run.
17187                mStartedUsers.remove(userId);
17188                mUserLru.remove(Integer.valueOf(userId));
17189                updateStartedUserArrayLocked();
17190
17191                // Clean up all state and processes associated with the user.
17192                // Kill all the processes for the user.
17193                forceStopUserLocked(userId, "finish user");
17194            }
17195        }
17196
17197        for (int i=0; i<callbacks.size(); i++) {
17198            try {
17199                if (stopped) callbacks.get(i).userStopped(userId);
17200                else callbacks.get(i).userStopAborted(userId);
17201            } catch (RemoteException e) {
17202            }
17203        }
17204
17205        if (stopped) {
17206            mSystemServiceManager.cleanupUser(userId);
17207            synchronized (this) {
17208                mStackSupervisor.removeUserLocked(userId);
17209            }
17210        }
17211    }
17212
17213    @Override
17214    public UserInfo getCurrentUser() {
17215        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17216                != PackageManager.PERMISSION_GRANTED) && (
17217                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17218                != PackageManager.PERMISSION_GRANTED)) {
17219            String msg = "Permission Denial: getCurrentUser() from pid="
17220                    + Binder.getCallingPid()
17221                    + ", uid=" + Binder.getCallingUid()
17222                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17223            Slog.w(TAG, msg);
17224            throw new SecurityException(msg);
17225        }
17226        synchronized (this) {
17227            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17228        }
17229    }
17230
17231    int getCurrentUserIdLocked() {
17232        return mCurrentUserId;
17233    }
17234
17235    @Override
17236    public boolean isUserRunning(int userId, boolean orStopped) {
17237        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17238                != PackageManager.PERMISSION_GRANTED) {
17239            String msg = "Permission Denial: isUserRunning() from pid="
17240                    + Binder.getCallingPid()
17241                    + ", uid=" + Binder.getCallingUid()
17242                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17243            Slog.w(TAG, msg);
17244            throw new SecurityException(msg);
17245        }
17246        synchronized (this) {
17247            return isUserRunningLocked(userId, orStopped);
17248        }
17249    }
17250
17251    boolean isUserRunningLocked(int userId, boolean orStopped) {
17252        UserStartedState state = mStartedUsers.get(userId);
17253        if (state == null) {
17254            return false;
17255        }
17256        if (orStopped) {
17257            return true;
17258        }
17259        return state.mState != UserStartedState.STATE_STOPPING
17260                && state.mState != UserStartedState.STATE_SHUTDOWN;
17261    }
17262
17263    @Override
17264    public int[] getRunningUserIds() {
17265        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17266                != PackageManager.PERMISSION_GRANTED) {
17267            String msg = "Permission Denial: isUserRunning() from pid="
17268                    + Binder.getCallingPid()
17269                    + ", uid=" + Binder.getCallingUid()
17270                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17271            Slog.w(TAG, msg);
17272            throw new SecurityException(msg);
17273        }
17274        synchronized (this) {
17275            return mStartedUserArray;
17276        }
17277    }
17278
17279    private void updateStartedUserArrayLocked() {
17280        int num = 0;
17281        for (int i=0; i<mStartedUsers.size();  i++) {
17282            UserStartedState uss = mStartedUsers.valueAt(i);
17283            // This list does not include stopping users.
17284            if (uss.mState != UserStartedState.STATE_STOPPING
17285                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17286                num++;
17287            }
17288        }
17289        mStartedUserArray = new int[num];
17290        num = 0;
17291        for (int i=0; i<mStartedUsers.size();  i++) {
17292            UserStartedState uss = mStartedUsers.valueAt(i);
17293            if (uss.mState != UserStartedState.STATE_STOPPING
17294                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17295                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17296                num++;
17297            }
17298        }
17299    }
17300
17301    @Override
17302    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17303        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17304                != PackageManager.PERMISSION_GRANTED) {
17305            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17306                    + Binder.getCallingPid()
17307                    + ", uid=" + Binder.getCallingUid()
17308                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17309            Slog.w(TAG, msg);
17310            throw new SecurityException(msg);
17311        }
17312
17313        mUserSwitchObservers.register(observer);
17314    }
17315
17316    @Override
17317    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17318        mUserSwitchObservers.unregister(observer);
17319    }
17320
17321    private boolean userExists(int userId) {
17322        if (userId == 0) {
17323            return true;
17324        }
17325        UserManagerService ums = getUserManagerLocked();
17326        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17327    }
17328
17329    int[] getUsersLocked() {
17330        UserManagerService ums = getUserManagerLocked();
17331        return ums != null ? ums.getUserIds() : new int[] { 0 };
17332    }
17333
17334    UserManagerService getUserManagerLocked() {
17335        if (mUserManager == null) {
17336            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17337            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17338        }
17339        return mUserManager;
17340    }
17341
17342    private int applyUserId(int uid, int userId) {
17343        return UserHandle.getUid(userId, uid);
17344    }
17345
17346    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17347        if (info == null) return null;
17348        ApplicationInfo newInfo = new ApplicationInfo(info);
17349        newInfo.uid = applyUserId(info.uid, userId);
17350        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17351                + info.packageName;
17352        return newInfo;
17353    }
17354
17355    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17356        if (aInfo == null
17357                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17358            return aInfo;
17359        }
17360
17361        ActivityInfo info = new ActivityInfo(aInfo);
17362        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17363        return info;
17364    }
17365
17366    private final class LocalService extends ActivityManagerInternal {
17367        @Override
17368        public void goingToSleep() {
17369            ActivityManagerService.this.goingToSleep();
17370        }
17371
17372        @Override
17373        public void wakingUp() {
17374            ActivityManagerService.this.wakingUp();
17375        }
17376    }
17377
17378    /**
17379     * An implementation of IAppTask, that allows an app to manage its own tasks via
17380     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17381     * only the process that calls getAppTasks() can call the AppTask methods.
17382     */
17383    class AppTaskImpl extends IAppTask.Stub {
17384        private int mTaskId;
17385        private int mCallingUid;
17386
17387        public AppTaskImpl(int taskId, int callingUid) {
17388            mTaskId = taskId;
17389            mCallingUid = callingUid;
17390        }
17391
17392        @Override
17393        public void finishAndRemoveTask() {
17394            // Ensure that we are called from the same process that created this AppTask
17395            if (mCallingUid != Binder.getCallingUid()) {
17396                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17397                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17398                return;
17399            }
17400
17401            synchronized (ActivityManagerService.this) {
17402                long origId = Binder.clearCallingIdentity();
17403                try {
17404                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17405                    if (tr != null) {
17406                        // Only kill the process if we are not a new document
17407                        int flags = tr.getBaseIntent().getFlags();
17408                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17409                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17410                        removeTaskByIdLocked(mTaskId,
17411                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17412                    }
17413                } finally {
17414                    Binder.restoreCallingIdentity(origId);
17415                }
17416            }
17417        }
17418
17419        @Override
17420        public ActivityManager.RecentTaskInfo getTaskInfo() {
17421            // Ensure that we are called from the same process that created this AppTask
17422            if (mCallingUid != Binder.getCallingUid()) {
17423                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17424                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17425                return null;
17426            }
17427
17428            synchronized (ActivityManagerService.this) {
17429                long origId = Binder.clearCallingIdentity();
17430                try {
17431                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17432                    if (tr != null) {
17433                        return createRecentTaskInfoFromTaskRecord(tr);
17434                    }
17435                } finally {
17436                    Binder.restoreCallingIdentity(origId);
17437                }
17438                return null;
17439            }
17440        }
17441    }
17442}
17443