ActivityManagerService.java revision dcb27fadcde2c45e14ee1658db4d16cc699ec250
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readBooleanAttribute;
21import static com.android.internal.util.XmlUtils.readIntAttribute;
22import static com.android.internal.util.XmlUtils.readLongAttribute;
23import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
24import static com.android.internal.util.XmlUtils.writeIntAttribute;
25import static com.android.internal.util.XmlUtils.writeLongAttribute;
26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
28import static org.xmlpull.v1.XmlPullParser.START_TAG;
29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
30
31import android.Manifest;
32import android.app.AppOpsManager;
33import android.app.IActivityContainer;
34import android.app.IActivityContainerCallback;
35import android.app.IAppTask;
36import android.appwidget.AppWidgetManager;
37import android.graphics.Rect;
38import android.os.BatteryStats;
39import android.os.PersistableBundle;
40import android.service.voice.IVoiceInteractionSession;
41import android.util.ArrayMap;
42
43import com.android.internal.R;
44import com.android.internal.annotations.GuardedBy;
45import com.android.internal.app.IAppOpsService;
46import com.android.internal.app.IVoiceInteractor;
47import com.android.internal.app.ProcessMap;
48import com.android.internal.app.ProcessStats;
49import com.android.internal.content.PackageMonitor;
50import com.android.internal.os.BackgroundThread;
51import com.android.internal.os.BatteryStatsImpl;
52import com.android.internal.os.ProcessCpuTracker;
53import com.android.internal.os.TransferPipe;
54import com.android.internal.os.Zygote;
55import com.android.internal.util.FastPrintWriter;
56import com.android.internal.util.FastXmlSerializer;
57import com.android.internal.util.MemInfoReader;
58import com.android.internal.util.Preconditions;
59import com.android.server.AppOpsService;
60import com.android.server.AttributeCache;
61import com.android.server.IntentResolver;
62import com.android.server.LocalServices;
63import com.android.server.ServiceThread;
64import com.android.server.SystemService;
65import com.android.server.SystemServiceManager;
66import com.android.server.Watchdog;
67import com.android.server.am.ActivityStack.ActivityState;
68import com.android.server.firewall.IntentFirewall;
69import com.android.server.pm.UserManagerService;
70import com.android.server.wm.AppTransition;
71import com.android.server.wm.WindowManagerService;
72import com.google.android.collect.Lists;
73import com.google.android.collect.Maps;
74
75import libcore.io.IoUtils;
76
77import org.xmlpull.v1.XmlPullParser;
78import org.xmlpull.v1.XmlPullParserException;
79import org.xmlpull.v1.XmlSerializer;
80
81import android.app.Activity;
82import android.app.ActivityManager;
83import android.app.ActivityManager.RunningTaskInfo;
84import android.app.ActivityManager.StackInfo;
85import android.app.ActivityManagerInternal;
86import android.app.ActivityManagerNative;
87import android.app.ActivityOptions;
88import android.app.ActivityThread;
89import android.app.AlertDialog;
90import android.app.AppGlobals;
91import android.app.ApplicationErrorReport;
92import android.app.Dialog;
93import android.app.IActivityController;
94import android.app.IApplicationThread;
95import android.app.IInstrumentationWatcher;
96import android.app.INotificationManager;
97import android.app.IProcessObserver;
98import android.app.IServiceConnection;
99import android.app.IStopUserCallback;
100import android.app.IUiAutomationConnection;
101import android.app.IUserSwitchObserver;
102import android.app.Instrumentation;
103import android.app.Notification;
104import android.app.NotificationManager;
105import android.app.PendingIntent;
106import android.app.backup.IBackupManager;
107import android.content.ActivityNotFoundException;
108import android.content.BroadcastReceiver;
109import android.content.ClipData;
110import android.content.ComponentCallbacks2;
111import android.content.ComponentName;
112import android.content.ContentProvider;
113import android.content.ContentResolver;
114import android.content.Context;
115import android.content.DialogInterface;
116import android.content.IContentProvider;
117import android.content.IIntentReceiver;
118import android.content.IIntentSender;
119import android.content.Intent;
120import android.content.IntentFilter;
121import android.content.IntentSender;
122import android.content.pm.ActivityInfo;
123import android.content.pm.ApplicationInfo;
124import android.content.pm.ConfigurationInfo;
125import android.content.pm.IPackageDataObserver;
126import android.content.pm.IPackageManager;
127import android.content.pm.InstrumentationInfo;
128import android.content.pm.PackageInfo;
129import android.content.pm.PackageManager;
130import android.content.pm.ParceledListSlice;
131import android.content.pm.UserInfo;
132import android.content.pm.PackageManager.NameNotFoundException;
133import android.content.pm.PathPermission;
134import android.content.pm.ProviderInfo;
135import android.content.pm.ResolveInfo;
136import android.content.pm.ServiceInfo;
137import android.content.res.CompatibilityInfo;
138import android.content.res.Configuration;
139import android.graphics.Bitmap;
140import android.net.Proxy;
141import android.net.ProxyInfo;
142import android.net.Uri;
143import android.os.Binder;
144import android.os.Build;
145import android.os.Bundle;
146import android.os.Debug;
147import android.os.DropBoxManager;
148import android.os.Environment;
149import android.os.FactoryTest;
150import android.os.FileObserver;
151import android.os.FileUtils;
152import android.os.Handler;
153import android.os.IBinder;
154import android.os.IPermissionController;
155import android.os.IRemoteCallback;
156import android.os.IUserManager;
157import android.os.Looper;
158import android.os.Message;
159import android.os.Parcel;
160import android.os.ParcelFileDescriptor;
161import android.os.Process;
162import android.os.RemoteCallbackList;
163import android.os.RemoteException;
164import android.os.SELinux;
165import android.os.ServiceManager;
166import android.os.StrictMode;
167import android.os.SystemClock;
168import android.os.SystemProperties;
169import android.os.UpdateLock;
170import android.os.UserHandle;
171import android.provider.Settings;
172import android.text.format.DateUtils;
173import android.text.format.Time;
174import android.util.AtomicFile;
175import android.util.EventLog;
176import android.util.Log;
177import android.util.Pair;
178import android.util.PrintWriterPrinter;
179import android.util.Slog;
180import android.util.SparseArray;
181import android.util.TimeUtils;
182import android.util.Xml;
183import android.view.Gravity;
184import android.view.LayoutInflater;
185import android.view.View;
186import android.view.WindowManager;
187
188import java.io.BufferedInputStream;
189import java.io.BufferedOutputStream;
190import java.io.DataInputStream;
191import java.io.DataOutputStream;
192import java.io.File;
193import java.io.FileDescriptor;
194import java.io.FileInputStream;
195import java.io.FileNotFoundException;
196import java.io.FileOutputStream;
197import java.io.IOException;
198import java.io.InputStreamReader;
199import java.io.PrintWriter;
200import java.io.StringWriter;
201import java.lang.ref.WeakReference;
202import java.util.ArrayList;
203import java.util.Arrays;
204import java.util.Collections;
205import java.util.Comparator;
206import java.util.HashMap;
207import java.util.HashSet;
208import java.util.Iterator;
209import java.util.List;
210import java.util.Locale;
211import java.util.Map;
212import java.util.Set;
213import java.util.concurrent.atomic.AtomicBoolean;
214import java.util.concurrent.atomic.AtomicLong;
215
216public final class ActivityManagerService extends ActivityManagerNative
217        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
218    private static final String USER_DATA_DIR = "/data/user/";
219    static final String TAG = "ActivityManager";
220    static final String TAG_MU = "ActivityManagerServiceMU";
221    static final boolean DEBUG = false;
222    static final boolean localLOGV = DEBUG;
223    static final boolean DEBUG_BACKUP = localLOGV || false;
224    static final boolean DEBUG_BROADCAST = localLOGV || false;
225    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
226    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
227    static final boolean DEBUG_CLEANUP = localLOGV || false;
228    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
229    static final boolean DEBUG_FOCUS = false;
230    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
231    static final boolean DEBUG_MU = localLOGV || false;
232    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
233    static final boolean DEBUG_LRU = localLOGV || false;
234    static final boolean DEBUG_PAUSE = localLOGV || false;
235    static final boolean DEBUG_POWER = localLOGV || false;
236    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
237    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
238    static final boolean DEBUG_PROCESSES = localLOGV || false;
239    static final boolean DEBUG_PROVIDER = localLOGV || false;
240    static final boolean DEBUG_RESULTS = localLOGV || false;
241    static final boolean DEBUG_SERVICE = localLOGV || false;
242    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
243    static final boolean DEBUG_STACK = localLOGV || false;
244    static final boolean DEBUG_SWITCH = localLOGV || false;
245    static final boolean DEBUG_TASKS = localLOGV || false;
246    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
247    static final boolean DEBUG_TRANSITION = localLOGV || false;
248    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
249    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
250    static final boolean DEBUG_VISBILITY = localLOGV || false;
251    static final boolean DEBUG_PSS = localLOGV || false;
252    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
253    static final boolean VALIDATE_TOKENS = false;
254    static final boolean SHOW_ACTIVITY_START_TIME = true;
255
256    // Control over CPU and battery monitoring.
257    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
258    static final boolean MONITOR_CPU_USAGE = true;
259    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
260    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
261    static final boolean MONITOR_THREAD_CPU_USAGE = false;
262
263    // The flags that are set for all calls we make to the package manager.
264    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
265
266    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
267
268    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
269
270    // Maximum number of recent tasks that we can remember.
271    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
272
273    // Amount of time after a call to stopAppSwitches() during which we will
274    // prevent further untrusted switches from happening.
275    static final long APP_SWITCH_DELAY_TIME = 5*1000;
276
277    // How long we wait for a launched process to attach to the activity manager
278    // before we decide it's never going to come up for real.
279    static final int PROC_START_TIMEOUT = 10*1000;
280
281    // How long we wait for a launched process to attach to the activity manager
282    // before we decide it's never going to come up for real, when the process was
283    // started with a wrapper for instrumentation (such as Valgrind) because it
284    // could take much longer than usual.
285    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
286
287    // How long to wait after going idle before forcing apps to GC.
288    static final int GC_TIMEOUT = 5*1000;
289
290    // The minimum amount of time between successive GC requests for a process.
291    static final int GC_MIN_INTERVAL = 60*1000;
292
293    // The minimum amount of time between successive PSS requests for a process.
294    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
295
296    // The minimum amount of time between successive PSS requests for a process
297    // when the request is due to the memory state being lowered.
298    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
299
300    // The rate at which we check for apps using excessive power -- 15 mins.
301    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
302
303    // The minimum sample duration we will allow before deciding we have
304    // enough data on wake locks to start killing things.
305    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
306
307    // The minimum sample duration we will allow before deciding we have
308    // enough data on CPU usage to start killing things.
309    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
310
311    // How long we allow a receiver to run before giving up on it.
312    static final int BROADCAST_FG_TIMEOUT = 10*1000;
313    static final int BROADCAST_BG_TIMEOUT = 60*1000;
314
315    // How long we wait until we timeout on key dispatching.
316    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
317
318    // How long we wait until we timeout on key dispatching during instrumentation.
319    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
320
321    // Amount of time we wait for observers to handle a user switch before
322    // giving up on them and unfreezing the screen.
323    static final int USER_SWITCH_TIMEOUT = 2*1000;
324
325    // Maximum number of users we allow to be running at a time.
326    static final int MAX_RUNNING_USERS = 3;
327
328    // How long to wait in getAssistContextExtras for the activity and foreground services
329    // to respond with the result.
330    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
331
332    // Maximum number of persisted Uri grants a package is allowed
333    static final int MAX_PERSISTED_URI_GRANTS = 128;
334
335    static final int MY_PID = Process.myPid();
336
337    static final String[] EMPTY_STRING_ARRAY = new String[0];
338
339    // How many bytes to write into the dropbox log before truncating
340    static final int DROPBOX_MAX_SIZE = 256 * 1024;
341
342    /** All system services */
343    SystemServiceManager mSystemServiceManager;
344
345    /** Run all ActivityStacks through this */
346    ActivityStackSupervisor mStackSupervisor;
347
348    public IntentFirewall mIntentFirewall;
349
350    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
351    // default actuion automatically.  Important for devices without direct input
352    // devices.
353    private boolean mShowDialogs = true;
354
355    /**
356     * Description of a request to start a new activity, which has been held
357     * due to app switches being disabled.
358     */
359    static class PendingActivityLaunch {
360        final ActivityRecord r;
361        final ActivityRecord sourceRecord;
362        final int startFlags;
363        final ActivityStack stack;
364
365        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
366                int _startFlags, ActivityStack _stack) {
367            r = _r;
368            sourceRecord = _sourceRecord;
369            startFlags = _startFlags;
370            stack = _stack;
371        }
372    }
373
374    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
375            = new ArrayList<PendingActivityLaunch>();
376
377    BroadcastQueue mFgBroadcastQueue;
378    BroadcastQueue mBgBroadcastQueue;
379    // Convenient for easy iteration over the queues. Foreground is first
380    // so that dispatch of foreground broadcasts gets precedence.
381    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
382
383    BroadcastQueue broadcastQueueForIntent(Intent intent) {
384        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
385        if (DEBUG_BACKGROUND_BROADCAST) {
386            Slog.i(TAG, "Broadcast intent " + intent + " on "
387                    + (isFg ? "foreground" : "background")
388                    + " queue");
389        }
390        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
391    }
392
393    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
394        for (BroadcastQueue queue : mBroadcastQueues) {
395            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
396            if (r != null) {
397                return r;
398            }
399        }
400        return null;
401    }
402
403    /**
404     * Activity we have told the window manager to have key focus.
405     */
406    ActivityRecord mFocusedActivity = null;
407
408    /**
409     * List of intents that were used to start the most recent tasks.
410     */
411    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * This is the process holding what we currently consider to be
572     * the "home" activity.
573     */
574    ProcessRecord mHomeProcess;
575
576    /**
577     * This is the process holding the activity the user last visited that
578     * is in a different process from the one they are currently in.
579     */
580    ProcessRecord mPreviousProcess;
581
582    /**
583     * The time at which the previous process was last visible.
584     */
585    long mPreviousProcessVisibleTime;
586
587    /**
588     * Which uses have been started, so are allowed to run code.
589     */
590    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
591
592    /**
593     * LRU list of history of current users.  Most recently current is at the end.
594     */
595    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
596
597    /**
598     * Constant array of the users that are currently started.
599     */
600    int[] mStartedUserArray = new int[] { 0 };
601
602    /**
603     * Registered observers of the user switching mechanics.
604     */
605    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
606            = new RemoteCallbackList<IUserSwitchObserver>();
607
608    /**
609     * Currently active user switch.
610     */
611    Object mCurUserSwitchCallback;
612
613    /**
614     * Packages that the user has asked to have run in screen size
615     * compatibility mode instead of filling the screen.
616     */
617    final CompatModePackages mCompatModePackages;
618
619    /**
620     * Set of IntentSenderRecord objects that are currently active.
621     */
622    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
623            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
624
625    /**
626     * Fingerprints (hashCode()) of stack traces that we've
627     * already logged DropBox entries for.  Guarded by itself.  If
628     * something (rogue user app) forces this over
629     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
630     */
631    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
632    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
633
634    /**
635     * Strict Mode background batched logging state.
636     *
637     * The string buffer is guarded by itself, and its lock is also
638     * used to determine if another batched write is already
639     * in-flight.
640     */
641    private final StringBuilder mStrictModeBuffer = new StringBuilder();
642
643    /**
644     * Keeps track of all IIntentReceivers that have been registered for
645     * broadcasts.  Hash keys are the receiver IBinder, hash value is
646     * a ReceiverList.
647     */
648    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
649            new HashMap<IBinder, ReceiverList>();
650
651    /**
652     * Resolver for broadcast intents to registered receivers.
653     * Holds BroadcastFilter (subclass of IntentFilter).
654     */
655    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
656            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
657        @Override
658        protected boolean allowFilterResult(
659                BroadcastFilter filter, List<BroadcastFilter> dest) {
660            IBinder target = filter.receiverList.receiver.asBinder();
661            for (int i=dest.size()-1; i>=0; i--) {
662                if (dest.get(i).receiverList.receiver.asBinder() == target) {
663                    return false;
664                }
665            }
666            return true;
667        }
668
669        @Override
670        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
671            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
672                    || userId == filter.owningUserId) {
673                return super.newResult(filter, match, userId);
674            }
675            return null;
676        }
677
678        @Override
679        protected BroadcastFilter[] newArray(int size) {
680            return new BroadcastFilter[size];
681        }
682
683        @Override
684        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
685            return packageName.equals(filter.packageName);
686        }
687    };
688
689    /**
690     * State of all active sticky broadcasts per user.  Keys are the action of the
691     * sticky Intent, values are an ArrayList of all broadcasted intents with
692     * that action (which should usually be one).  The SparseArray is keyed
693     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
694     * for stickies that are sent to all users.
695     */
696    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
697            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
698
699    final ActiveServices mServices;
700
701    /**
702     * Backup/restore process management
703     */
704    String mBackupAppName = null;
705    BackupRecord mBackupTarget = null;
706
707    final ProviderMap mProviderMap;
708
709    /**
710     * List of content providers who have clients waiting for them.  The
711     * application is currently being launched and the provider will be
712     * removed from this list once it is published.
713     */
714    final ArrayList<ContentProviderRecord> mLaunchingProviders
715            = new ArrayList<ContentProviderRecord>();
716
717    /**
718     * File storing persisted {@link #mGrantedUriPermissions}.
719     */
720    private final AtomicFile mGrantFile;
721
722    /** XML constants used in {@link #mGrantFile} */
723    private static final String TAG_URI_GRANTS = "uri-grants";
724    private static final String TAG_URI_GRANT = "uri-grant";
725    private static final String ATTR_USER_HANDLE = "userHandle";
726    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
727    private static final String ATTR_TARGET_USER_ID = "targetUserId";
728    private static final String ATTR_SOURCE_PKG = "sourcePkg";
729    private static final String ATTR_TARGET_PKG = "targetPkg";
730    private static final String ATTR_URI = "uri";
731    private static final String ATTR_MODE_FLAGS = "modeFlags";
732    private static final String ATTR_CREATED_TIME = "createdTime";
733    private static final String ATTR_PREFIX = "prefix";
734
735    /**
736     * Global set of specific {@link Uri} permissions that have been granted.
737     * This optimized lookup structure maps from {@link UriPermission#targetUid}
738     * to {@link UriPermission#uri} to {@link UriPermission}.
739     */
740    @GuardedBy("this")
741    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
742            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
743
744    public static class GrantUri {
745        public final int sourceUserId;
746        public final Uri uri;
747        public boolean prefix;
748
749        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
750            this.sourceUserId = sourceUserId;
751            this.uri = uri;
752            this.prefix = prefix;
753        }
754
755        @Override
756        public int hashCode() {
757            return toString().hashCode();
758        }
759
760        @Override
761        public boolean equals(Object o) {
762            if (o instanceof GrantUri) {
763                GrantUri other = (GrantUri) o;
764                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
765                        && prefix == other.prefix;
766            }
767            return false;
768        }
769
770        @Override
771        public String toString() {
772            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
773            if (prefix) result += " [prefix]";
774            return result;
775        }
776
777        public String toSafeString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
784            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
785                    ContentProvider.getUriWithoutUserId(uri), false);
786        }
787    }
788
789    CoreSettingsObserver mCoreSettingsObserver;
790
791    /**
792     * Thread-local storage used to carry caller permissions over through
793     * indirect content-provider access.
794     */
795    private class Identity {
796        public int pid;
797        public int uid;
798
799        Identity(int _pid, int _uid) {
800            pid = _pid;
801            uid = _uid;
802        }
803    }
804
805    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
806
807    /**
808     * All information we have collected about the runtime performance of
809     * any user id that can impact battery performance.
810     */
811    final BatteryStatsService mBatteryStatsService;
812
813    /**
814     * Information about component usage
815     */
816    final UsageStatsService mUsageStatsService;
817
818    /**
819     * Information about and control over application operations
820     */
821    final AppOpsService mAppOpsService;
822
823    /**
824     * Current configuration information.  HistoryRecord objects are given
825     * a reference to this object to indicate which configuration they are
826     * currently running in, so this object must be kept immutable.
827     */
828    Configuration mConfiguration = new Configuration();
829
830    /**
831     * Current sequencing integer of the configuration, for skipping old
832     * configurations.
833     */
834    int mConfigurationSeq = 0;
835
836    /**
837     * Hardware-reported OpenGLES version.
838     */
839    final int GL_ES_VERSION;
840
841    /**
842     * List of initialization arguments to pass to all processes when binding applications to them.
843     * For example, references to the commonly used services.
844     */
845    HashMap<String, IBinder> mAppBindArgs;
846
847    /**
848     * Temporary to avoid allocations.  Protected by main lock.
849     */
850    final StringBuilder mStringBuilder = new StringBuilder(256);
851
852    /**
853     * Used to control how we initialize the service.
854     */
855    ComponentName mTopComponent;
856    String mTopAction = Intent.ACTION_MAIN;
857    String mTopData;
858    boolean mProcessesReady = false;
859    boolean mSystemReady = false;
860    boolean mBooting = false;
861    boolean mWaitingUpdate = false;
862    boolean mDidUpdate = false;
863    boolean mOnBattery = false;
864    boolean mLaunchWarningShown = false;
865
866    Context mContext;
867
868    int mFactoryTest;
869
870    boolean mCheckedForSetup;
871
872    /**
873     * The time at which we will allow normal application switches again,
874     * after a call to {@link #stopAppSwitches()}.
875     */
876    long mAppSwitchesAllowedTime;
877
878    /**
879     * This is set to true after the first switch after mAppSwitchesAllowedTime
880     * is set; any switches after that will clear the time.
881     */
882    boolean mDidAppSwitch;
883
884    /**
885     * Last time (in realtime) at which we checked for power usage.
886     */
887    long mLastPowerCheckRealtime;
888
889    /**
890     * Last time (in uptime) at which we checked for power usage.
891     */
892    long mLastPowerCheckUptime;
893
894    /**
895     * Set while we are wanting to sleep, to prevent any
896     * activities from being started/resumed.
897     */
898    private boolean mSleeping = false;
899
900    /**
901     * Set while we are running a voice interaction.  This overrides
902     * sleeping while it is active.
903     */
904    private boolean mRunningVoice = false;
905
906    /**
907     * State of external calls telling us if the device is asleep.
908     */
909    private boolean mWentToSleep = false;
910
911    /**
912     * State of external call telling us if the lock screen is shown.
913     */
914    private boolean mLockScreenShown = false;
915
916    /**
917     * Set if we are shutting down the system, similar to sleeping.
918     */
919    boolean mShuttingDown = false;
920
921    /**
922     * Current sequence id for oom_adj computation traversal.
923     */
924    int mAdjSeq = 0;
925
926    /**
927     * Current sequence id for process LRU updating.
928     */
929    int mLruSeq = 0;
930
931    /**
932     * Keep track of the non-cached/empty process we last found, to help
933     * determine how to distribute cached/empty processes next time.
934     */
935    int mNumNonCachedProcs = 0;
936
937    /**
938     * Keep track of the number of cached hidden procs, to balance oom adj
939     * distribution between those and empty procs.
940     */
941    int mNumCachedHiddenProcs = 0;
942
943    /**
944     * Keep track of the number of service processes we last found, to
945     * determine on the next iteration which should be B services.
946     */
947    int mNumServiceProcs = 0;
948    int mNewNumAServiceProcs = 0;
949    int mNewNumServiceProcs = 0;
950
951    /**
952     * Allow the current computed overall memory level of the system to go down?
953     * This is set to false when we are killing processes for reasons other than
954     * memory management, so that the now smaller process list will not be taken as
955     * an indication that memory is tighter.
956     */
957    boolean mAllowLowerMemLevel = false;
958
959    /**
960     * The last computed memory level, for holding when we are in a state that
961     * processes are going away for other reasons.
962     */
963    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
964
965    /**
966     * The last total number of process we have, to determine if changes actually look
967     * like a shrinking number of process due to lower RAM.
968     */
969    int mLastNumProcesses;
970
971    /**
972     * The uptime of the last time we performed idle maintenance.
973     */
974    long mLastIdleTime = SystemClock.uptimeMillis();
975
976    /**
977     * Total time spent with RAM that has been added in the past since the last idle time.
978     */
979    long mLowRamTimeSinceLastIdle = 0;
980
981    /**
982     * If RAM is currently low, when that horrible situation started.
983     */
984    long mLowRamStartTime = 0;
985
986    /**
987     * For reporting to battery stats the current top application.
988     */
989    private String mCurResumedPackage = null;
990    private int mCurResumedUid = -1;
991
992    /**
993     * For reporting to battery stats the apps currently running foreground
994     * service.  The ProcessMap is package/uid tuples; each of these contain
995     * an array of the currently foreground processes.
996     */
997    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
998            = new ProcessMap<ArrayList<ProcessRecord>>();
999
1000    /**
1001     * This is set if we had to do a delayed dexopt of an app before launching
1002     * it, to increase the ANR timeouts in that case.
1003     */
1004    boolean mDidDexOpt;
1005
1006    /**
1007     * Set if the systemServer made a call to enterSafeMode.
1008     */
1009    boolean mSafeMode;
1010
1011    String mDebugApp = null;
1012    boolean mWaitForDebugger = false;
1013    boolean mDebugTransient = false;
1014    String mOrigDebugApp = null;
1015    boolean mOrigWaitForDebugger = false;
1016    boolean mAlwaysFinishActivities = false;
1017    IActivityController mController = null;
1018    String mProfileApp = null;
1019    ProcessRecord mProfileProc = null;
1020    String mProfileFile;
1021    ParcelFileDescriptor mProfileFd;
1022    int mProfileType = 0;
1023    boolean mAutoStopProfiler = false;
1024    String mOpenGlTraceApp = null;
1025
1026    static class ProcessChangeItem {
1027        static final int CHANGE_ACTIVITIES = 1<<0;
1028        static final int CHANGE_PROCESS_STATE = 1<<1;
1029        int changes;
1030        int uid;
1031        int pid;
1032        int processState;
1033        boolean foregroundActivities;
1034    }
1035
1036    final RemoteCallbackList<IProcessObserver> mProcessObservers
1037            = new RemoteCallbackList<IProcessObserver>();
1038    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1039
1040    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1041            = new ArrayList<ProcessChangeItem>();
1042    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1043            = new ArrayList<ProcessChangeItem>();
1044
1045    /**
1046     * Runtime CPU use collection thread.  This object's lock is used to
1047     * protect all related state.
1048     */
1049    final Thread mProcessCpuThread;
1050
1051    /**
1052     * Used to collect process stats when showing not responding dialog.
1053     * Protected by mProcessCpuThread.
1054     */
1055    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1056            MONITOR_THREAD_CPU_USAGE);
1057    final AtomicLong mLastCpuTime = new AtomicLong(0);
1058    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1059
1060    long mLastWriteTime = 0;
1061
1062    /**
1063     * Used to retain an update lock when the foreground activity is in
1064     * immersive mode.
1065     */
1066    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1067
1068    /**
1069     * Set to true after the system has finished booting.
1070     */
1071    boolean mBooted = false;
1072
1073    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1074    int mProcessLimitOverride = -1;
1075
1076    WindowManagerService mWindowManager;
1077
1078    final ActivityThread mSystemThread;
1079
1080    int mCurrentUserId = 0;
1081    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1082    private UserManagerService mUserManager;
1083
1084    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1085        final ProcessRecord mApp;
1086        final int mPid;
1087        final IApplicationThread mAppThread;
1088
1089        AppDeathRecipient(ProcessRecord app, int pid,
1090                IApplicationThread thread) {
1091            if (localLOGV) Slog.v(
1092                TAG, "New death recipient " + this
1093                + " for thread " + thread.asBinder());
1094            mApp = app;
1095            mPid = pid;
1096            mAppThread = thread;
1097        }
1098
1099        @Override
1100        public void binderDied() {
1101            if (localLOGV) Slog.v(
1102                TAG, "Death received in " + this
1103                + " for thread " + mAppThread.asBinder());
1104            synchronized(ActivityManagerService.this) {
1105                appDiedLocked(mApp, mPid, mAppThread);
1106            }
1107        }
1108    }
1109
1110    static final int SHOW_ERROR_MSG = 1;
1111    static final int SHOW_NOT_RESPONDING_MSG = 2;
1112    static final int SHOW_FACTORY_ERROR_MSG = 3;
1113    static final int UPDATE_CONFIGURATION_MSG = 4;
1114    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1115    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1116    static final int SERVICE_TIMEOUT_MSG = 12;
1117    static final int UPDATE_TIME_ZONE = 13;
1118    static final int SHOW_UID_ERROR_MSG = 14;
1119    static final int IM_FEELING_LUCKY_MSG = 15;
1120    static final int PROC_START_TIMEOUT_MSG = 20;
1121    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1122    static final int KILL_APPLICATION_MSG = 22;
1123    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1124    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1125    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1126    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1127    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1128    static final int CLEAR_DNS_CACHE_MSG = 28;
1129    static final int UPDATE_HTTP_PROXY_MSG = 29;
1130    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1131    static final int DISPATCH_PROCESSES_CHANGED = 31;
1132    static final int DISPATCH_PROCESS_DIED = 32;
1133    static final int REPORT_MEM_USAGE_MSG = 33;
1134    static final int REPORT_USER_SWITCH_MSG = 34;
1135    static final int CONTINUE_USER_SWITCH_MSG = 35;
1136    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1137    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1138    static final int PERSIST_URI_GRANTS_MSG = 38;
1139    static final int REQUEST_ALL_PSS_MSG = 39;
1140    static final int START_PROFILES_MSG = 40;
1141    static final int UPDATE_TIME = 41;
1142    static final int SYSTEM_USER_START_MSG = 42;
1143    static final int SYSTEM_USER_CURRENT_MSG = 43;
1144
1145    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1146    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1147    static final int FIRST_COMPAT_MODE_MSG = 300;
1148    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1149
1150    AlertDialog mUidAlert;
1151    CompatModeDialog mCompatModeDialog;
1152    long mLastMemUsageReportTime = 0;
1153
1154    /**
1155     * Flag whether the current user is a "monkey", i.e. whether
1156     * the UI is driven by a UI automation tool.
1157     */
1158    private boolean mUserIsMonkey;
1159
1160    final ServiceThread mHandlerThread;
1161    final MainHandler mHandler;
1162
1163    final class MainHandler extends Handler {
1164        public MainHandler(Looper looper) {
1165            super(looper, null, true);
1166        }
1167
1168        @Override
1169        public void handleMessage(Message msg) {
1170            switch (msg.what) {
1171            case SHOW_ERROR_MSG: {
1172                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1173                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1174                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1175                synchronized (ActivityManagerService.this) {
1176                    ProcessRecord proc = (ProcessRecord)data.get("app");
1177                    AppErrorResult res = (AppErrorResult) data.get("result");
1178                    if (proc != null && proc.crashDialog != null) {
1179                        Slog.e(TAG, "App already has crash dialog: " + proc);
1180                        if (res != null) {
1181                            res.set(0);
1182                        }
1183                        return;
1184                    }
1185                    if (!showBackground && UserHandle.getAppId(proc.uid)
1186                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1187                            && proc.pid != MY_PID) {
1188                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1189                        if (res != null) {
1190                            res.set(0);
1191                        }
1192                        return;
1193                    }
1194                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1195                        Dialog d = new AppErrorDialog(mContext,
1196                                ActivityManagerService.this, res, proc);
1197                        d.show();
1198                        proc.crashDialog = d;
1199                    } else {
1200                        // The device is asleep, so just pretend that the user
1201                        // saw a crash dialog and hit "force quit".
1202                        if (res != null) {
1203                            res.set(0);
1204                        }
1205                    }
1206                }
1207
1208                ensureBootCompleted();
1209            } break;
1210            case SHOW_NOT_RESPONDING_MSG: {
1211                synchronized (ActivityManagerService.this) {
1212                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1213                    ProcessRecord proc = (ProcessRecord)data.get("app");
1214                    if (proc != null && proc.anrDialog != null) {
1215                        Slog.e(TAG, "App already has anr dialog: " + proc);
1216                        return;
1217                    }
1218
1219                    Intent intent = new Intent("android.intent.action.ANR");
1220                    if (!mProcessesReady) {
1221                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1222                                | Intent.FLAG_RECEIVER_FOREGROUND);
1223                    }
1224                    broadcastIntentLocked(null, null, intent,
1225                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1226                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1227
1228                    if (mShowDialogs) {
1229                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1230                                mContext, proc, (ActivityRecord)data.get("activity"),
1231                                msg.arg1 != 0);
1232                        d.show();
1233                        proc.anrDialog = d;
1234                    } else {
1235                        // Just kill the app if there is no dialog to be shown.
1236                        killAppAtUsersRequest(proc, null);
1237                    }
1238                }
1239
1240                ensureBootCompleted();
1241            } break;
1242            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1243                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1244                synchronized (ActivityManagerService.this) {
1245                    ProcessRecord proc = (ProcessRecord) data.get("app");
1246                    if (proc == null) {
1247                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1248                        break;
1249                    }
1250                    if (proc.crashDialog != null) {
1251                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1252                        return;
1253                    }
1254                    AppErrorResult res = (AppErrorResult) data.get("result");
1255                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1256                        Dialog d = new StrictModeViolationDialog(mContext,
1257                                ActivityManagerService.this, res, proc);
1258                        d.show();
1259                        proc.crashDialog = d;
1260                    } else {
1261                        // The device is asleep, so just pretend that the user
1262                        // saw a crash dialog and hit "force quit".
1263                        res.set(0);
1264                    }
1265                }
1266                ensureBootCompleted();
1267            } break;
1268            case SHOW_FACTORY_ERROR_MSG: {
1269                Dialog d = new FactoryErrorDialog(
1270                    mContext, msg.getData().getCharSequence("msg"));
1271                d.show();
1272                ensureBootCompleted();
1273            } break;
1274            case UPDATE_CONFIGURATION_MSG: {
1275                final ContentResolver resolver = mContext.getContentResolver();
1276                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1277            } break;
1278            case GC_BACKGROUND_PROCESSES_MSG: {
1279                synchronized (ActivityManagerService.this) {
1280                    performAppGcsIfAppropriateLocked();
1281                }
1282            } break;
1283            case WAIT_FOR_DEBUGGER_MSG: {
1284                synchronized (ActivityManagerService.this) {
1285                    ProcessRecord app = (ProcessRecord)msg.obj;
1286                    if (msg.arg1 != 0) {
1287                        if (!app.waitedForDebugger) {
1288                            Dialog d = new AppWaitingForDebuggerDialog(
1289                                    ActivityManagerService.this,
1290                                    mContext, app);
1291                            app.waitDialog = d;
1292                            app.waitedForDebugger = true;
1293                            d.show();
1294                        }
1295                    } else {
1296                        if (app.waitDialog != null) {
1297                            app.waitDialog.dismiss();
1298                            app.waitDialog = null;
1299                        }
1300                    }
1301                }
1302            } break;
1303            case SERVICE_TIMEOUT_MSG: {
1304                if (mDidDexOpt) {
1305                    mDidDexOpt = false;
1306                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1307                    nmsg.obj = msg.obj;
1308                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1309                    return;
1310                }
1311                mServices.serviceTimeout((ProcessRecord)msg.obj);
1312            } break;
1313            case UPDATE_TIME_ZONE: {
1314                synchronized (ActivityManagerService.this) {
1315                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1316                        ProcessRecord r = mLruProcesses.get(i);
1317                        if (r.thread != null) {
1318                            try {
1319                                r.thread.updateTimeZone();
1320                            } catch (RemoteException ex) {
1321                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1322                            }
1323                        }
1324                    }
1325                }
1326            } break;
1327            case CLEAR_DNS_CACHE_MSG: {
1328                synchronized (ActivityManagerService.this) {
1329                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1330                        ProcessRecord r = mLruProcesses.get(i);
1331                        if (r.thread != null) {
1332                            try {
1333                                r.thread.clearDnsCache();
1334                            } catch (RemoteException ex) {
1335                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1336                            }
1337                        }
1338                    }
1339                }
1340            } break;
1341            case UPDATE_HTTP_PROXY_MSG: {
1342                ProxyInfo proxy = (ProxyInfo)msg.obj;
1343                String host = "";
1344                String port = "";
1345                String exclList = "";
1346                Uri pacFileUrl = Uri.EMPTY;
1347                if (proxy != null) {
1348                    host = proxy.getHost();
1349                    port = Integer.toString(proxy.getPort());
1350                    exclList = proxy.getExclusionListAsString();
1351                    pacFileUrl = proxy.getPacFileUrl();
1352                }
1353                synchronized (ActivityManagerService.this) {
1354                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1355                        ProcessRecord r = mLruProcesses.get(i);
1356                        if (r.thread != null) {
1357                            try {
1358                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1359                            } catch (RemoteException ex) {
1360                                Slog.w(TAG, "Failed to update http proxy for: " +
1361                                        r.info.processName);
1362                            }
1363                        }
1364                    }
1365                }
1366            } break;
1367            case SHOW_UID_ERROR_MSG: {
1368                String title = "System UIDs Inconsistent";
1369                String text = "UIDs on the system are inconsistent, you need to wipe your"
1370                        + " data partition or your device will be unstable.";
1371                Log.e(TAG, title + ": " + text);
1372                if (mShowDialogs) {
1373                    // XXX This is a temporary dialog, no need to localize.
1374                    AlertDialog d = new BaseErrorDialog(mContext);
1375                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1376                    d.setCancelable(false);
1377                    d.setTitle(title);
1378                    d.setMessage(text);
1379                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1380                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1381                    mUidAlert = d;
1382                    d.show();
1383                }
1384            } break;
1385            case IM_FEELING_LUCKY_MSG: {
1386                if (mUidAlert != null) {
1387                    mUidAlert.dismiss();
1388                    mUidAlert = null;
1389                }
1390            } break;
1391            case PROC_START_TIMEOUT_MSG: {
1392                if (mDidDexOpt) {
1393                    mDidDexOpt = false;
1394                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1395                    nmsg.obj = msg.obj;
1396                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1397                    return;
1398                }
1399                ProcessRecord app = (ProcessRecord)msg.obj;
1400                synchronized (ActivityManagerService.this) {
1401                    processStartTimedOutLocked(app);
1402                }
1403            } break;
1404            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1405                synchronized (ActivityManagerService.this) {
1406                    doPendingActivityLaunchesLocked(true);
1407                }
1408            } break;
1409            case KILL_APPLICATION_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    int appid = msg.arg1;
1412                    boolean restart = (msg.arg2 == 1);
1413                    Bundle bundle = (Bundle)msg.obj;
1414                    String pkg = bundle.getString("pkg");
1415                    String reason = bundle.getString("reason");
1416                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1417                            false, UserHandle.USER_ALL, reason);
1418                }
1419            } break;
1420            case FINALIZE_PENDING_INTENT_MSG: {
1421                ((PendingIntentRecord)msg.obj).completeFinalize();
1422            } break;
1423            case POST_HEAVY_NOTIFICATION_MSG: {
1424                INotificationManager inm = NotificationManager.getService();
1425                if (inm == null) {
1426                    return;
1427                }
1428
1429                ActivityRecord root = (ActivityRecord)msg.obj;
1430                ProcessRecord process = root.app;
1431                if (process == null) {
1432                    return;
1433                }
1434
1435                try {
1436                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1437                    String text = mContext.getString(R.string.heavy_weight_notification,
1438                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1439                    Notification notification = new Notification();
1440                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1441                    notification.when = 0;
1442                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1443                    notification.tickerText = text;
1444                    notification.defaults = 0; // please be quiet
1445                    notification.sound = null;
1446                    notification.vibrate = null;
1447                    notification.setLatestEventInfo(context, text,
1448                            mContext.getText(R.string.heavy_weight_notification_detail),
1449                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1450                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1451                                    new UserHandle(root.userId)));
1452
1453                    try {
1454                        int[] outId = new int[1];
1455                        inm.enqueueNotificationWithTag("android", "android", null,
1456                                R.string.heavy_weight_notification,
1457                                notification, outId, root.userId);
1458                    } catch (RuntimeException e) {
1459                        Slog.w(ActivityManagerService.TAG,
1460                                "Error showing notification for heavy-weight app", e);
1461                    } catch (RemoteException e) {
1462                    }
1463                } catch (NameNotFoundException e) {
1464                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1465                }
1466            } break;
1467            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1468                INotificationManager inm = NotificationManager.getService();
1469                if (inm == null) {
1470                    return;
1471                }
1472                try {
1473                    inm.cancelNotificationWithTag("android", null,
1474                            R.string.heavy_weight_notification,  msg.arg1);
1475                } catch (RuntimeException e) {
1476                    Slog.w(ActivityManagerService.TAG,
1477                            "Error canceling notification for service", e);
1478                } catch (RemoteException e) {
1479                }
1480            } break;
1481            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1482                synchronized (ActivityManagerService.this) {
1483                    checkExcessivePowerUsageLocked(true);
1484                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1485                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1486                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1487                }
1488            } break;
1489            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1490                synchronized (ActivityManagerService.this) {
1491                    ActivityRecord ar = (ActivityRecord)msg.obj;
1492                    if (mCompatModeDialog != null) {
1493                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1494                                ar.info.applicationInfo.packageName)) {
1495                            return;
1496                        }
1497                        mCompatModeDialog.dismiss();
1498                        mCompatModeDialog = null;
1499                    }
1500                    if (ar != null && false) {
1501                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1502                                ar.packageName)) {
1503                            int mode = mCompatModePackages.computeCompatModeLocked(
1504                                    ar.info.applicationInfo);
1505                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1506                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1507                                mCompatModeDialog = new CompatModeDialog(
1508                                        ActivityManagerService.this, mContext,
1509                                        ar.info.applicationInfo);
1510                                mCompatModeDialog.show();
1511                            }
1512                        }
1513                    }
1514                }
1515                break;
1516            }
1517            case DISPATCH_PROCESSES_CHANGED: {
1518                dispatchProcessesChanged();
1519                break;
1520            }
1521            case DISPATCH_PROCESS_DIED: {
1522                final int pid = msg.arg1;
1523                final int uid = msg.arg2;
1524                dispatchProcessDied(pid, uid);
1525                break;
1526            }
1527            case REPORT_MEM_USAGE_MSG: {
1528                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1529                Thread thread = new Thread() {
1530                    @Override public void run() {
1531                        final SparseArray<ProcessMemInfo> infoMap
1532                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1533                        for (int i=0, N=memInfos.size(); i<N; i++) {
1534                            ProcessMemInfo mi = memInfos.get(i);
1535                            infoMap.put(mi.pid, mi);
1536                        }
1537                        updateCpuStatsNow();
1538                        synchronized (mProcessCpuThread) {
1539                            final int N = mProcessCpuTracker.countStats();
1540                            for (int i=0; i<N; i++) {
1541                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1542                                if (st.vsize > 0) {
1543                                    long pss = Debug.getPss(st.pid, null);
1544                                    if (pss > 0) {
1545                                        if (infoMap.indexOfKey(st.pid) < 0) {
1546                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1547                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1548                                            mi.pss = pss;
1549                                            memInfos.add(mi);
1550                                        }
1551                                    }
1552                                }
1553                            }
1554                        }
1555
1556                        long totalPss = 0;
1557                        for (int i=0, N=memInfos.size(); i<N; i++) {
1558                            ProcessMemInfo mi = memInfos.get(i);
1559                            if (mi.pss == 0) {
1560                                mi.pss = Debug.getPss(mi.pid, null);
1561                            }
1562                            totalPss += mi.pss;
1563                        }
1564                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1565                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1566                                if (lhs.oomAdj != rhs.oomAdj) {
1567                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1568                                }
1569                                if (lhs.pss != rhs.pss) {
1570                                    return lhs.pss < rhs.pss ? 1 : -1;
1571                                }
1572                                return 0;
1573                            }
1574                        });
1575
1576                        StringBuilder tag = new StringBuilder(128);
1577                        StringBuilder stack = new StringBuilder(128);
1578                        tag.append("Low on memory -- ");
1579                        appendMemBucket(tag, totalPss, "total", false);
1580                        appendMemBucket(stack, totalPss, "total", true);
1581
1582                        StringBuilder logBuilder = new StringBuilder(1024);
1583                        logBuilder.append("Low on memory:\n");
1584
1585                        boolean firstLine = true;
1586                        int lastOomAdj = Integer.MIN_VALUE;
1587                        for (int i=0, N=memInfos.size(); i<N; i++) {
1588                            ProcessMemInfo mi = memInfos.get(i);
1589
1590                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1591                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1592                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1593                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1594                                if (lastOomAdj != mi.oomAdj) {
1595                                    lastOomAdj = mi.oomAdj;
1596                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1597                                        tag.append(" / ");
1598                                    }
1599                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1600                                        if (firstLine) {
1601                                            stack.append(":");
1602                                            firstLine = false;
1603                                        }
1604                                        stack.append("\n\t at ");
1605                                    } else {
1606                                        stack.append("$");
1607                                    }
1608                                } else {
1609                                    tag.append(" ");
1610                                    stack.append("$");
1611                                }
1612                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1613                                    appendMemBucket(tag, mi.pss, mi.name, false);
1614                                }
1615                                appendMemBucket(stack, mi.pss, mi.name, true);
1616                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1617                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1618                                    stack.append("(");
1619                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1620                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1621                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1622                                            stack.append(":");
1623                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1624                                        }
1625                                    }
1626                                    stack.append(")");
1627                                }
1628                            }
1629
1630                            logBuilder.append("  ");
1631                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1632                            logBuilder.append(' ');
1633                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1634                            logBuilder.append(' ');
1635                            ProcessList.appendRamKb(logBuilder, mi.pss);
1636                            logBuilder.append(" kB: ");
1637                            logBuilder.append(mi.name);
1638                            logBuilder.append(" (");
1639                            logBuilder.append(mi.pid);
1640                            logBuilder.append(") ");
1641                            logBuilder.append(mi.adjType);
1642                            logBuilder.append('\n');
1643                            if (mi.adjReason != null) {
1644                                logBuilder.append("                      ");
1645                                logBuilder.append(mi.adjReason);
1646                                logBuilder.append('\n');
1647                            }
1648                        }
1649
1650                        logBuilder.append("           ");
1651                        ProcessList.appendRamKb(logBuilder, totalPss);
1652                        logBuilder.append(" kB: TOTAL\n");
1653
1654                        long[] infos = new long[Debug.MEMINFO_COUNT];
1655                        Debug.getMemInfo(infos);
1656                        logBuilder.append("  MemInfo: ");
1657                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1658                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1659                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1660                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1661                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1662                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1663                            logBuilder.append("  ZRAM: ");
1664                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1665                            logBuilder.append(" kB RAM, ");
1666                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1667                            logBuilder.append(" kB swap total, ");
1668                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1669                            logBuilder.append(" kB swap free\n");
1670                        }
1671                        Slog.i(TAG, logBuilder.toString());
1672
1673                        StringBuilder dropBuilder = new StringBuilder(1024);
1674                        /*
1675                        StringWriter oomSw = new StringWriter();
1676                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1677                        StringWriter catSw = new StringWriter();
1678                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1679                        String[] emptyArgs = new String[] { };
1680                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1681                        oomPw.flush();
1682                        String oomString = oomSw.toString();
1683                        */
1684                        dropBuilder.append(stack);
1685                        dropBuilder.append('\n');
1686                        dropBuilder.append('\n');
1687                        dropBuilder.append(logBuilder);
1688                        dropBuilder.append('\n');
1689                        /*
1690                        dropBuilder.append(oomString);
1691                        dropBuilder.append('\n');
1692                        */
1693                        StringWriter catSw = new StringWriter();
1694                        synchronized (ActivityManagerService.this) {
1695                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1696                            String[] emptyArgs = new String[] { };
1697                            catPw.println();
1698                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1699                            catPw.println();
1700                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1701                                    false, false, null);
1702                            catPw.println();
1703                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1704                            catPw.flush();
1705                        }
1706                        dropBuilder.append(catSw.toString());
1707                        addErrorToDropBox("lowmem", null, "system_server", null,
1708                                null, tag.toString(), dropBuilder.toString(), null, null);
1709                        //Slog.i(TAG, "Sent to dropbox:");
1710                        //Slog.i(TAG, dropBuilder.toString());
1711                        synchronized (ActivityManagerService.this) {
1712                            long now = SystemClock.uptimeMillis();
1713                            if (mLastMemUsageReportTime < now) {
1714                                mLastMemUsageReportTime = now;
1715                            }
1716                        }
1717                    }
1718                };
1719                thread.start();
1720                break;
1721            }
1722            case REPORT_USER_SWITCH_MSG: {
1723                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1724                break;
1725            }
1726            case CONTINUE_USER_SWITCH_MSG: {
1727                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1728                break;
1729            }
1730            case USER_SWITCH_TIMEOUT_MSG: {
1731                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1732                break;
1733            }
1734            case IMMERSIVE_MODE_LOCK_MSG: {
1735                final boolean nextState = (msg.arg1 != 0);
1736                if (mUpdateLock.isHeld() != nextState) {
1737                    if (DEBUG_IMMERSIVE) {
1738                        final ActivityRecord r = (ActivityRecord) msg.obj;
1739                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1740                    }
1741                    if (nextState) {
1742                        mUpdateLock.acquire();
1743                    } else {
1744                        mUpdateLock.release();
1745                    }
1746                }
1747                break;
1748            }
1749            case PERSIST_URI_GRANTS_MSG: {
1750                writeGrantedUriPermissions();
1751                break;
1752            }
1753            case REQUEST_ALL_PSS_MSG: {
1754                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1755                break;
1756            }
1757            case START_PROFILES_MSG: {
1758                synchronized (ActivityManagerService.this) {
1759                    startProfilesLocked();
1760                }
1761                break;
1762            }
1763            case UPDATE_TIME: {
1764                synchronized (ActivityManagerService.this) {
1765                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1766                        ProcessRecord r = mLruProcesses.get(i);
1767                        if (r.thread != null) {
1768                            try {
1769                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1770                            } catch (RemoteException ex) {
1771                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1772                            }
1773                        }
1774                    }
1775                }
1776                break;
1777            }
1778            case SYSTEM_USER_START_MSG: {
1779                mSystemServiceManager.startUser(msg.arg1);
1780                break;
1781            }
1782            case SYSTEM_USER_CURRENT_MSG: {
1783                mSystemServiceManager.switchUser(msg.arg1);
1784                break;
1785            }
1786            }
1787        }
1788    };
1789
1790    static final int COLLECT_PSS_BG_MSG = 1;
1791
1792    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1793        @Override
1794        public void handleMessage(Message msg) {
1795            switch (msg.what) {
1796            case COLLECT_PSS_BG_MSG: {
1797                int i=0, num=0;
1798                long start = SystemClock.uptimeMillis();
1799                long[] tmp = new long[1];
1800                do {
1801                    ProcessRecord proc;
1802                    int procState;
1803                    int pid;
1804                    synchronized (ActivityManagerService.this) {
1805                        if (i >= mPendingPssProcesses.size()) {
1806                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1807                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1808                            mPendingPssProcesses.clear();
1809                            return;
1810                        }
1811                        proc = mPendingPssProcesses.get(i);
1812                        procState = proc.pssProcState;
1813                        if (proc.thread != null && procState == proc.setProcState) {
1814                            pid = proc.pid;
1815                        } else {
1816                            proc = null;
1817                            pid = 0;
1818                        }
1819                        i++;
1820                    }
1821                    if (proc != null) {
1822                        long pss = Debug.getPss(pid, tmp);
1823                        synchronized (ActivityManagerService.this) {
1824                            if (proc.thread != null && proc.setProcState == procState
1825                                    && proc.pid == pid) {
1826                                num++;
1827                                proc.lastPssTime = SystemClock.uptimeMillis();
1828                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1829                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1830                                        + ": " + pss + " lastPss=" + proc.lastPss
1831                                        + " state=" + ProcessList.makeProcStateString(procState));
1832                                if (proc.initialIdlePss == 0) {
1833                                    proc.initialIdlePss = pss;
1834                                }
1835                                proc.lastPss = pss;
1836                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1837                                    proc.lastCachedPss = pss;
1838                                }
1839                            }
1840                        }
1841                    }
1842                } while (true);
1843            }
1844            }
1845        }
1846    };
1847
1848    /**
1849     * Monitor for package changes and update our internal state.
1850     */
1851    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1852        @Override
1853        public void onPackageRemoved(String packageName, int uid) {
1854            // Remove all tasks with activities in the specified package from the list of recent tasks
1855            synchronized (ActivityManagerService.this) {
1856                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1857                    TaskRecord tr = mRecentTasks.get(i);
1858                    ComponentName cn = tr.intent.getComponent();
1859                    if (cn != null && cn.getPackageName().equals(packageName)) {
1860                        // If the package name matches, remove the task and kill the process
1861                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1862                    }
1863                }
1864            }
1865        }
1866
1867        @Override
1868        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1869            onPackageModified(packageName);
1870            return true;
1871        }
1872
1873        @Override
1874        public void onPackageModified(String packageName) {
1875            final PackageManager pm = mContext.getPackageManager();
1876            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1877                    new ArrayList<Pair<Intent, Integer>>();
1878            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1879            // Copy the list of recent tasks so that we don't hold onto the lock on
1880            // ActivityManagerService for long periods while checking if components exist.
1881            synchronized (ActivityManagerService.this) {
1882                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1883                    TaskRecord tr = mRecentTasks.get(i);
1884                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1885                }
1886            }
1887            // Check the recent tasks and filter out all tasks with components that no longer exist.
1888            Intent tmpI = new Intent();
1889            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1890                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1891                ComponentName cn = p.first.getComponent();
1892                if (cn != null && cn.getPackageName().equals(packageName)) {
1893                    try {
1894                        // Add the task to the list to remove if the component no longer exists
1895                        tmpI.setComponent(cn);
1896                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1897                            tasksToRemove.add(p.second);
1898                        }
1899                    } catch (Exception e) {}
1900                }
1901            }
1902            // Prune all the tasks with removed components from the list of recent tasks
1903            synchronized (ActivityManagerService.this) {
1904                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1905                    // Remove the task but don't kill the process (since other components in that
1906                    // package may still be running and in the background)
1907                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1908                }
1909            }
1910        }
1911
1912        @Override
1913        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1914            // Force stop the specified packages
1915            if (packages != null) {
1916                for (String pkg : packages) {
1917                    synchronized (ActivityManagerService.this) {
1918                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1919                                "finished booting")) {
1920                            return true;
1921                        }
1922                    }
1923                }
1924            }
1925            return false;
1926        }
1927    };
1928
1929    public void setSystemProcess() {
1930        try {
1931            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1932            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1933            ServiceManager.addService("meminfo", new MemBinder(this));
1934            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1935            ServiceManager.addService("dbinfo", new DbBinder(this));
1936            if (MONITOR_CPU_USAGE) {
1937                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1938            }
1939            ServiceManager.addService("permission", new PermissionController(this));
1940
1941            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1942                    "android", STOCK_PM_FLAGS);
1943            mSystemThread.installSystemApplicationInfo(info);
1944
1945            synchronized (this) {
1946                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1947                app.persistent = true;
1948                app.pid = MY_PID;
1949                app.maxAdj = ProcessList.SYSTEM_ADJ;
1950                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1951                mProcessNames.put(app.processName, app.uid, app);
1952                synchronized (mPidsSelfLocked) {
1953                    mPidsSelfLocked.put(app.pid, app);
1954                }
1955                updateLruProcessLocked(app, false, null);
1956                updateOomAdjLocked();
1957            }
1958        } catch (PackageManager.NameNotFoundException e) {
1959            throw new RuntimeException(
1960                    "Unable to find android system package", e);
1961        }
1962    }
1963
1964    public void setWindowManager(WindowManagerService wm) {
1965        mWindowManager = wm;
1966        mStackSupervisor.setWindowManager(wm);
1967    }
1968
1969    public void startObservingNativeCrashes() {
1970        final NativeCrashListener ncl = new NativeCrashListener(this);
1971        ncl.start();
1972    }
1973
1974    public IAppOpsService getAppOpsService() {
1975        return mAppOpsService;
1976    }
1977
1978    static class MemBinder extends Binder {
1979        ActivityManagerService mActivityManagerService;
1980        MemBinder(ActivityManagerService activityManagerService) {
1981            mActivityManagerService = activityManagerService;
1982        }
1983
1984        @Override
1985        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1986            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1987                    != PackageManager.PERMISSION_GRANTED) {
1988                pw.println("Permission Denial: can't dump meminfo from from pid="
1989                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1990                        + " without permission " + android.Manifest.permission.DUMP);
1991                return;
1992            }
1993
1994            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1995        }
1996    }
1997
1998    static class GraphicsBinder extends Binder {
1999        ActivityManagerService mActivityManagerService;
2000        GraphicsBinder(ActivityManagerService activityManagerService) {
2001            mActivityManagerService = activityManagerService;
2002        }
2003
2004        @Override
2005        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2006            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2007                    != PackageManager.PERMISSION_GRANTED) {
2008                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2009                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2010                        + " without permission " + android.Manifest.permission.DUMP);
2011                return;
2012            }
2013
2014            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2015        }
2016    }
2017
2018    static class DbBinder extends Binder {
2019        ActivityManagerService mActivityManagerService;
2020        DbBinder(ActivityManagerService activityManagerService) {
2021            mActivityManagerService = activityManagerService;
2022        }
2023
2024        @Override
2025        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2026            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2027                    != PackageManager.PERMISSION_GRANTED) {
2028                pw.println("Permission Denial: can't dump dbinfo from from pid="
2029                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2030                        + " without permission " + android.Manifest.permission.DUMP);
2031                return;
2032            }
2033
2034            mActivityManagerService.dumpDbInfo(fd, pw, args);
2035        }
2036    }
2037
2038    static class CpuBinder extends Binder {
2039        ActivityManagerService mActivityManagerService;
2040        CpuBinder(ActivityManagerService activityManagerService) {
2041            mActivityManagerService = activityManagerService;
2042        }
2043
2044        @Override
2045        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2046            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2047                    != PackageManager.PERMISSION_GRANTED) {
2048                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2049                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2050                        + " without permission " + android.Manifest.permission.DUMP);
2051                return;
2052            }
2053
2054            synchronized (mActivityManagerService.mProcessCpuThread) {
2055                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2056                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2057                        SystemClock.uptimeMillis()));
2058            }
2059        }
2060    }
2061
2062    public static final class Lifecycle extends SystemService {
2063        private final ActivityManagerService mService;
2064
2065        public Lifecycle(Context context) {
2066            super(context);
2067            mService = new ActivityManagerService(context);
2068        }
2069
2070        @Override
2071        public void onStart() {
2072            mService.start();
2073        }
2074
2075        public ActivityManagerService getService() {
2076            return mService;
2077        }
2078    }
2079
2080    // Note: This method is invoked on the main thread but may need to attach various
2081    // handlers to other threads.  So take care to be explicit about the looper.
2082    public ActivityManagerService(Context systemContext) {
2083        mContext = systemContext;
2084        mFactoryTest = FactoryTest.getMode();
2085        mSystemThread = ActivityThread.currentActivityThread();
2086
2087        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2088
2089        mHandlerThread = new ServiceThread(TAG,
2090                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2091        mHandlerThread.start();
2092        mHandler = new MainHandler(mHandlerThread.getLooper());
2093
2094        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2095                "foreground", BROADCAST_FG_TIMEOUT, false);
2096        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2097                "background", BROADCAST_BG_TIMEOUT, true);
2098        mBroadcastQueues[0] = mFgBroadcastQueue;
2099        mBroadcastQueues[1] = mBgBroadcastQueue;
2100
2101        mServices = new ActiveServices(this);
2102        mProviderMap = new ProviderMap(this);
2103
2104        // TODO: Move creation of battery stats service outside of activity manager service.
2105        File dataDir = Environment.getDataDirectory();
2106        File systemDir = new File(dataDir, "system");
2107        systemDir.mkdirs();
2108        mBatteryStatsService = new BatteryStatsService(new File(
2109                systemDir, "batterystats.bin").toString(), mHandler);
2110        mBatteryStatsService.getActiveStatistics().readLocked();
2111        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2112        mOnBattery = DEBUG_POWER ? true
2113                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2114        mBatteryStatsService.getActiveStatistics().setCallback(this);
2115
2116        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2117
2118        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2119        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2120
2121        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2122
2123        // User 0 is the first and only user that runs at boot.
2124        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2125        mUserLru.add(Integer.valueOf(0));
2126        updateStartedUserArrayLocked();
2127
2128        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2129            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2130
2131        mConfiguration.setToDefaults();
2132        mConfiguration.setLocale(Locale.getDefault());
2133
2134        mConfigurationSeq = mConfiguration.seq = 1;
2135        mProcessCpuTracker.init();
2136
2137        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2138        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2139        mStackSupervisor = new ActivityStackSupervisor(this);
2140
2141        mProcessCpuThread = new Thread("CpuTracker") {
2142            @Override
2143            public void run() {
2144                while (true) {
2145                    try {
2146                        try {
2147                            synchronized(this) {
2148                                final long now = SystemClock.uptimeMillis();
2149                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2150                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2151                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2152                                //        + ", write delay=" + nextWriteDelay);
2153                                if (nextWriteDelay < nextCpuDelay) {
2154                                    nextCpuDelay = nextWriteDelay;
2155                                }
2156                                if (nextCpuDelay > 0) {
2157                                    mProcessCpuMutexFree.set(true);
2158                                    this.wait(nextCpuDelay);
2159                                }
2160                            }
2161                        } catch (InterruptedException e) {
2162                        }
2163                        updateCpuStatsNow();
2164                    } catch (Exception e) {
2165                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2166                    }
2167                }
2168            }
2169        };
2170
2171        Watchdog.getInstance().addMonitor(this);
2172        Watchdog.getInstance().addThread(mHandler);
2173    }
2174
2175    public void setSystemServiceManager(SystemServiceManager mgr) {
2176        mSystemServiceManager = mgr;
2177    }
2178
2179    private void start() {
2180        mProcessCpuThread.start();
2181
2182        mBatteryStatsService.publish(mContext);
2183        mUsageStatsService.publish(mContext);
2184        mAppOpsService.publish(mContext);
2185
2186        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2187    }
2188
2189    @Override
2190    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2191            throws RemoteException {
2192        if (code == SYSPROPS_TRANSACTION) {
2193            // We need to tell all apps about the system property change.
2194            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2195            synchronized(this) {
2196                final int NP = mProcessNames.getMap().size();
2197                for (int ip=0; ip<NP; ip++) {
2198                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2199                    final int NA = apps.size();
2200                    for (int ia=0; ia<NA; ia++) {
2201                        ProcessRecord app = apps.valueAt(ia);
2202                        if (app.thread != null) {
2203                            procs.add(app.thread.asBinder());
2204                        }
2205                    }
2206                }
2207            }
2208
2209            int N = procs.size();
2210            for (int i=0; i<N; i++) {
2211                Parcel data2 = Parcel.obtain();
2212                try {
2213                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2214                } catch (RemoteException e) {
2215                }
2216                data2.recycle();
2217            }
2218        }
2219        try {
2220            return super.onTransact(code, data, reply, flags);
2221        } catch (RuntimeException e) {
2222            // The activity manager only throws security exceptions, so let's
2223            // log all others.
2224            if (!(e instanceof SecurityException)) {
2225                Slog.wtf(TAG, "Activity Manager Crash", e);
2226            }
2227            throw e;
2228        }
2229    }
2230
2231    void updateCpuStats() {
2232        final long now = SystemClock.uptimeMillis();
2233        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2234            return;
2235        }
2236        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2237            synchronized (mProcessCpuThread) {
2238                mProcessCpuThread.notify();
2239            }
2240        }
2241    }
2242
2243    void updateCpuStatsNow() {
2244        synchronized (mProcessCpuThread) {
2245            mProcessCpuMutexFree.set(false);
2246            final long now = SystemClock.uptimeMillis();
2247            boolean haveNewCpuStats = false;
2248
2249            if (MONITOR_CPU_USAGE &&
2250                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2251                mLastCpuTime.set(now);
2252                haveNewCpuStats = true;
2253                mProcessCpuTracker.update();
2254                //Slog.i(TAG, mProcessCpu.printCurrentState());
2255                //Slog.i(TAG, "Total CPU usage: "
2256                //        + mProcessCpu.getTotalCpuPercent() + "%");
2257
2258                // Slog the cpu usage if the property is set.
2259                if ("true".equals(SystemProperties.get("events.cpu"))) {
2260                    int user = mProcessCpuTracker.getLastUserTime();
2261                    int system = mProcessCpuTracker.getLastSystemTime();
2262                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2263                    int irq = mProcessCpuTracker.getLastIrqTime();
2264                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2265                    int idle = mProcessCpuTracker.getLastIdleTime();
2266
2267                    int total = user + system + iowait + irq + softIrq + idle;
2268                    if (total == 0) total = 1;
2269
2270                    EventLog.writeEvent(EventLogTags.CPU,
2271                            ((user+system+iowait+irq+softIrq) * 100) / total,
2272                            (user * 100) / total,
2273                            (system * 100) / total,
2274                            (iowait * 100) / total,
2275                            (irq * 100) / total,
2276                            (softIrq * 100) / total);
2277                }
2278            }
2279
2280            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2281            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2282            synchronized(bstats) {
2283                synchronized(mPidsSelfLocked) {
2284                    if (haveNewCpuStats) {
2285                        if (mOnBattery) {
2286                            int perc = bstats.startAddingCpuLocked();
2287                            int totalUTime = 0;
2288                            int totalSTime = 0;
2289                            final int N = mProcessCpuTracker.countStats();
2290                            for (int i=0; i<N; i++) {
2291                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2292                                if (!st.working) {
2293                                    continue;
2294                                }
2295                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2296                                int otherUTime = (st.rel_utime*perc)/100;
2297                                int otherSTime = (st.rel_stime*perc)/100;
2298                                totalUTime += otherUTime;
2299                                totalSTime += otherSTime;
2300                                if (pr != null) {
2301                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2302                                    if (ps == null || !ps.isActive()) {
2303                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2304                                                pr.info.uid, pr.processName);
2305                                    }
2306                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2307                                            st.rel_stime-otherSTime);
2308                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2309                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2310                                } else {
2311                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2312                                    if (ps == null || !ps.isActive()) {
2313                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2314                                                bstats.mapUid(st.uid), st.name);
2315                                    }
2316                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2317                                            st.rel_stime-otherSTime);
2318                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2319                                }
2320                            }
2321                            bstats.finishAddingCpuLocked(perc, totalUTime,
2322                                    totalSTime, cpuSpeedTimes);
2323                        }
2324                    }
2325                }
2326
2327                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2328                    mLastWriteTime = now;
2329                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2330                }
2331            }
2332        }
2333    }
2334
2335    @Override
2336    public void batteryNeedsCpuUpdate() {
2337        updateCpuStatsNow();
2338    }
2339
2340    @Override
2341    public void batteryPowerChanged(boolean onBattery) {
2342        // When plugging in, update the CPU stats first before changing
2343        // the plug state.
2344        updateCpuStatsNow();
2345        synchronized (this) {
2346            synchronized(mPidsSelfLocked) {
2347                mOnBattery = DEBUG_POWER ? true : onBattery;
2348            }
2349        }
2350    }
2351
2352    /**
2353     * Initialize the application bind args. These are passed to each
2354     * process when the bindApplication() IPC is sent to the process. They're
2355     * lazily setup to make sure the services are running when they're asked for.
2356     */
2357    private HashMap<String, IBinder> getCommonServicesLocked() {
2358        if (mAppBindArgs == null) {
2359            mAppBindArgs = new HashMap<String, IBinder>();
2360
2361            // Setup the application init args
2362            mAppBindArgs.put("package", ServiceManager.getService("package"));
2363            mAppBindArgs.put("window", ServiceManager.getService("window"));
2364            mAppBindArgs.put(Context.ALARM_SERVICE,
2365                    ServiceManager.getService(Context.ALARM_SERVICE));
2366        }
2367        return mAppBindArgs;
2368    }
2369
2370    final void setFocusedActivityLocked(ActivityRecord r) {
2371        if (mFocusedActivity != r) {
2372            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2373            mFocusedActivity = r;
2374            if (r.task != null && r.task.voiceInteractor != null) {
2375                startRunningVoiceLocked();
2376            } else {
2377                finishRunningVoiceLocked();
2378            }
2379            mStackSupervisor.setFocusedStack(r);
2380            if (r != null) {
2381                mWindowManager.setFocusedApp(r.appToken, true);
2382            }
2383            applyUpdateLockStateLocked(r);
2384        }
2385    }
2386
2387    final void clearFocusedActivity(ActivityRecord r) {
2388        if (mFocusedActivity == r) {
2389            mFocusedActivity = null;
2390        }
2391    }
2392
2393    @Override
2394    public void setFocusedStack(int stackId) {
2395        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2396        synchronized (ActivityManagerService.this) {
2397            ActivityStack stack = mStackSupervisor.getStack(stackId);
2398            if (stack != null) {
2399                ActivityRecord r = stack.topRunningActivityLocked(null);
2400                if (r != null) {
2401                    setFocusedActivityLocked(r);
2402                }
2403            }
2404        }
2405    }
2406
2407    @Override
2408    public void notifyActivityDrawn(IBinder token) {
2409        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2410        synchronized (this) {
2411            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2412            if (r != null) {
2413                r.task.stack.notifyActivityDrawnLocked(r);
2414            }
2415        }
2416    }
2417
2418    final void applyUpdateLockStateLocked(ActivityRecord r) {
2419        // Modifications to the UpdateLock state are done on our handler, outside
2420        // the activity manager's locks.  The new state is determined based on the
2421        // state *now* of the relevant activity record.  The object is passed to
2422        // the handler solely for logging detail, not to be consulted/modified.
2423        final boolean nextState = r != null && r.immersive;
2424        mHandler.sendMessage(
2425                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2426    }
2427
2428    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2429        Message msg = Message.obtain();
2430        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2431        msg.obj = r.task.askedCompatMode ? null : r;
2432        mHandler.sendMessage(msg);
2433    }
2434
2435    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2436            String what, Object obj, ProcessRecord srcApp) {
2437        app.lastActivityTime = now;
2438
2439        if (app.activities.size() > 0) {
2440            // Don't want to touch dependent processes that are hosting activities.
2441            return index;
2442        }
2443
2444        int lrui = mLruProcesses.lastIndexOf(app);
2445        if (lrui < 0) {
2446            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2447                    + what + " " + obj + " from " + srcApp);
2448            return index;
2449        }
2450
2451        if (lrui >= index) {
2452            // Don't want to cause this to move dependent processes *back* in the
2453            // list as if they were less frequently used.
2454            return index;
2455        }
2456
2457        if (lrui >= mLruProcessActivityStart) {
2458            // Don't want to touch dependent processes that are hosting activities.
2459            return index;
2460        }
2461
2462        mLruProcesses.remove(lrui);
2463        if (index > 0) {
2464            index--;
2465        }
2466        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2467                + " in LRU list: " + app);
2468        mLruProcesses.add(index, app);
2469        return index;
2470    }
2471
2472    final void removeLruProcessLocked(ProcessRecord app) {
2473        int lrui = mLruProcesses.lastIndexOf(app);
2474        if (lrui >= 0) {
2475            if (lrui <= mLruProcessActivityStart) {
2476                mLruProcessActivityStart--;
2477            }
2478            if (lrui <= mLruProcessServiceStart) {
2479                mLruProcessServiceStart--;
2480            }
2481            mLruProcesses.remove(lrui);
2482        }
2483    }
2484
2485    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2486            ProcessRecord client) {
2487        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2488                || app.treatLikeActivity;
2489        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2490        if (!activityChange && hasActivity) {
2491            // The process has activities, so we are only allowing activity-based adjustments
2492            // to move it.  It should be kept in the front of the list with other
2493            // processes that have activities, and we don't want those to change their
2494            // order except due to activity operations.
2495            return;
2496        }
2497
2498        mLruSeq++;
2499        final long now = SystemClock.uptimeMillis();
2500        app.lastActivityTime = now;
2501
2502        // First a quick reject: if the app is already at the position we will
2503        // put it, then there is nothing to do.
2504        if (hasActivity) {
2505            final int N = mLruProcesses.size();
2506            if (N > 0 && mLruProcesses.get(N-1) == app) {
2507                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2508                return;
2509            }
2510        } else {
2511            if (mLruProcessServiceStart > 0
2512                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2513                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2514                return;
2515            }
2516        }
2517
2518        int lrui = mLruProcesses.lastIndexOf(app);
2519
2520        if (app.persistent && lrui >= 0) {
2521            // We don't care about the position of persistent processes, as long as
2522            // they are in the list.
2523            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2524            return;
2525        }
2526
2527        /* In progress: compute new position first, so we can avoid doing work
2528           if the process is not actually going to move.  Not yet working.
2529        int addIndex;
2530        int nextIndex;
2531        boolean inActivity = false, inService = false;
2532        if (hasActivity) {
2533            // Process has activities, put it at the very tipsy-top.
2534            addIndex = mLruProcesses.size();
2535            nextIndex = mLruProcessServiceStart;
2536            inActivity = true;
2537        } else if (hasService) {
2538            // Process has services, put it at the top of the service list.
2539            addIndex = mLruProcessActivityStart;
2540            nextIndex = mLruProcessServiceStart;
2541            inActivity = true;
2542            inService = true;
2543        } else  {
2544            // Process not otherwise of interest, it goes to the top of the non-service area.
2545            addIndex = mLruProcessServiceStart;
2546            if (client != null) {
2547                int clientIndex = mLruProcesses.lastIndexOf(client);
2548                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2549                        + app);
2550                if (clientIndex >= 0 && addIndex > clientIndex) {
2551                    addIndex = clientIndex;
2552                }
2553            }
2554            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2555        }
2556
2557        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2558                + mLruProcessActivityStart + "): " + app);
2559        */
2560
2561        if (lrui >= 0) {
2562            if (lrui < mLruProcessActivityStart) {
2563                mLruProcessActivityStart--;
2564            }
2565            if (lrui < mLruProcessServiceStart) {
2566                mLruProcessServiceStart--;
2567            }
2568            /*
2569            if (addIndex > lrui) {
2570                addIndex--;
2571            }
2572            if (nextIndex > lrui) {
2573                nextIndex--;
2574            }
2575            */
2576            mLruProcesses.remove(lrui);
2577        }
2578
2579        /*
2580        mLruProcesses.add(addIndex, app);
2581        if (inActivity) {
2582            mLruProcessActivityStart++;
2583        }
2584        if (inService) {
2585            mLruProcessActivityStart++;
2586        }
2587        */
2588
2589        int nextIndex;
2590        if (hasActivity) {
2591            final int N = mLruProcesses.size();
2592            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2593                // Process doesn't have activities, but has clients with
2594                // activities...  move it up, but one below the top (the top
2595                // should always have a real activity).
2596                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2597                mLruProcesses.add(N-1, app);
2598                // To keep it from spamming the LRU list (by making a bunch of clients),
2599                // we will push down any other entries owned by the app.
2600                final int uid = app.info.uid;
2601                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2602                    ProcessRecord subProc = mLruProcesses.get(i);
2603                    if (subProc.info.uid == uid) {
2604                        // We want to push this one down the list.  If the process after
2605                        // it is for the same uid, however, don't do so, because we don't
2606                        // want them internally to be re-ordered.
2607                        if (mLruProcesses.get(i-1).info.uid != uid) {
2608                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2609                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2610                            ProcessRecord tmp = mLruProcesses.get(i);
2611                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2612                            mLruProcesses.set(i-1, tmp);
2613                            i--;
2614                        }
2615                    } else {
2616                        // A gap, we can stop here.
2617                        break;
2618                    }
2619                }
2620            } else {
2621                // Process has activities, put it at the very tipsy-top.
2622                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2623                mLruProcesses.add(app);
2624            }
2625            nextIndex = mLruProcessServiceStart;
2626        } else if (hasService) {
2627            // Process has services, put it at the top of the service list.
2628            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2629            mLruProcesses.add(mLruProcessActivityStart, app);
2630            nextIndex = mLruProcessServiceStart;
2631            mLruProcessActivityStart++;
2632        } else  {
2633            // Process not otherwise of interest, it goes to the top of the non-service area.
2634            int index = mLruProcessServiceStart;
2635            if (client != null) {
2636                // If there is a client, don't allow the process to be moved up higher
2637                // in the list than that client.
2638                int clientIndex = mLruProcesses.lastIndexOf(client);
2639                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2640                        + " when updating " + app);
2641                if (clientIndex <= lrui) {
2642                    // Don't allow the client index restriction to push it down farther in the
2643                    // list than it already is.
2644                    clientIndex = lrui;
2645                }
2646                if (clientIndex >= 0 && index > clientIndex) {
2647                    index = clientIndex;
2648                }
2649            }
2650            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2651            mLruProcesses.add(index, app);
2652            nextIndex = index-1;
2653            mLruProcessActivityStart++;
2654            mLruProcessServiceStart++;
2655        }
2656
2657        // If the app is currently using a content provider or service,
2658        // bump those processes as well.
2659        for (int j=app.connections.size()-1; j>=0; j--) {
2660            ConnectionRecord cr = app.connections.valueAt(j);
2661            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2662                    && cr.binding.service.app != null
2663                    && cr.binding.service.app.lruSeq != mLruSeq
2664                    && !cr.binding.service.app.persistent) {
2665                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2666                        "service connection", cr, app);
2667            }
2668        }
2669        for (int j=app.conProviders.size()-1; j>=0; j--) {
2670            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2671            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2672                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2673                        "provider reference", cpr, app);
2674            }
2675        }
2676    }
2677
2678    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2679        if (uid == Process.SYSTEM_UID) {
2680            // The system gets to run in any process.  If there are multiple
2681            // processes with the same uid, just pick the first (this
2682            // should never happen).
2683            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2684            if (procs == null) return null;
2685            final int N = procs.size();
2686            for (int i = 0; i < N; i++) {
2687                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2688            }
2689        }
2690        ProcessRecord proc = mProcessNames.get(processName, uid);
2691        if (false && proc != null && !keepIfLarge
2692                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2693                && proc.lastCachedPss >= 4000) {
2694            // Turn this condition on to cause killing to happen regularly, for testing.
2695            if (proc.baseProcessTracker != null) {
2696                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2697            }
2698            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2699                    + "k from cached");
2700        } else if (proc != null && !keepIfLarge
2701                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2702                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2703            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2704            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2705                if (proc.baseProcessTracker != null) {
2706                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2707                }
2708                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2709                        + "k from cached");
2710            }
2711        }
2712        return proc;
2713    }
2714
2715    void ensurePackageDexOpt(String packageName) {
2716        IPackageManager pm = AppGlobals.getPackageManager();
2717        try {
2718            if (pm.performDexOpt(packageName)) {
2719                mDidDexOpt = true;
2720            }
2721        } catch (RemoteException e) {
2722        }
2723    }
2724
2725    boolean isNextTransitionForward() {
2726        int transit = mWindowManager.getPendingAppTransition();
2727        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2728                || transit == AppTransition.TRANSIT_TASK_OPEN
2729                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2730    }
2731
2732    final ProcessRecord startProcessLocked(String processName,
2733            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2734            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2735            boolean isolated, boolean keepIfLarge) {
2736        ProcessRecord app;
2737        if (!isolated) {
2738            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2739        } else {
2740            // If this is an isolated process, it can't re-use an existing process.
2741            app = null;
2742        }
2743        // We don't have to do anything more if:
2744        // (1) There is an existing application record; and
2745        // (2) The caller doesn't think it is dead, OR there is no thread
2746        //     object attached to it so we know it couldn't have crashed; and
2747        // (3) There is a pid assigned to it, so it is either starting or
2748        //     already running.
2749        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2750                + " app=" + app + " knownToBeDead=" + knownToBeDead
2751                + " thread=" + (app != null ? app.thread : null)
2752                + " pid=" + (app != null ? app.pid : -1));
2753        if (app != null && app.pid > 0) {
2754            if (!knownToBeDead || app.thread == null) {
2755                // We already have the app running, or are waiting for it to
2756                // come up (we have a pid but not yet its thread), so keep it.
2757                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2758                // If this is a new package in the process, add the package to the list
2759                app.addPackage(info.packageName, mProcessStats);
2760                return app;
2761            }
2762
2763            // An application record is attached to a previous process,
2764            // clean it up now.
2765            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2766            handleAppDiedLocked(app, true, true);
2767        }
2768
2769        String hostingNameStr = hostingName != null
2770                ? hostingName.flattenToShortString() : null;
2771
2772        if (!isolated) {
2773            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2774                // If we are in the background, then check to see if this process
2775                // is bad.  If so, we will just silently fail.
2776                if (mBadProcesses.get(info.processName, info.uid) != null) {
2777                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2778                            + "/" + info.processName);
2779                    return null;
2780                }
2781            } else {
2782                // When the user is explicitly starting a process, then clear its
2783                // crash count so that we won't make it bad until they see at
2784                // least one crash dialog again, and make the process good again
2785                // if it had been bad.
2786                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2787                        + "/" + info.processName);
2788                mProcessCrashTimes.remove(info.processName, info.uid);
2789                if (mBadProcesses.get(info.processName, info.uid) != null) {
2790                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2791                            UserHandle.getUserId(info.uid), info.uid,
2792                            info.processName);
2793                    mBadProcesses.remove(info.processName, info.uid);
2794                    if (app != null) {
2795                        app.bad = false;
2796                    }
2797                }
2798            }
2799        }
2800
2801        if (app == null) {
2802            app = newProcessRecordLocked(info, processName, isolated);
2803            if (app == null) {
2804                Slog.w(TAG, "Failed making new process record for "
2805                        + processName + "/" + info.uid + " isolated=" + isolated);
2806                return null;
2807            }
2808            mProcessNames.put(processName, app.uid, app);
2809            if (isolated) {
2810                mIsolatedProcesses.put(app.uid, app);
2811            }
2812        } else {
2813            // If this is a new package in the process, add the package to the list
2814            app.addPackage(info.packageName, mProcessStats);
2815        }
2816
2817        // If the system is not ready yet, then hold off on starting this
2818        // process until it is.
2819        if (!mProcessesReady
2820                && !isAllowedWhileBooting(info)
2821                && !allowWhileBooting) {
2822            if (!mProcessesOnHold.contains(app)) {
2823                mProcessesOnHold.add(app);
2824            }
2825            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2826            return app;
2827        }
2828
2829        startProcessLocked(app, hostingType, hostingNameStr);
2830        return (app.pid != 0) ? app : null;
2831    }
2832
2833    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2834        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2835    }
2836
2837    private final void startProcessLocked(ProcessRecord app,
2838            String hostingType, String hostingNameStr) {
2839        if (app.pid > 0 && app.pid != MY_PID) {
2840            synchronized (mPidsSelfLocked) {
2841                mPidsSelfLocked.remove(app.pid);
2842                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2843            }
2844            app.setPid(0);
2845        }
2846
2847        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2848                "startProcessLocked removing on hold: " + app);
2849        mProcessesOnHold.remove(app);
2850
2851        updateCpuStats();
2852
2853        try {
2854            int uid = app.uid;
2855
2856            int[] gids = null;
2857            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2858            if (!app.isolated) {
2859                int[] permGids = null;
2860                try {
2861                    final PackageManager pm = mContext.getPackageManager();
2862                    permGids = pm.getPackageGids(app.info.packageName);
2863
2864                    if (Environment.isExternalStorageEmulated()) {
2865                        if (pm.checkPermission(
2866                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2867                                app.info.packageName) == PERMISSION_GRANTED) {
2868                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2869                        } else {
2870                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2871                        }
2872                    }
2873                } catch (PackageManager.NameNotFoundException e) {
2874                    Slog.w(TAG, "Unable to retrieve gids", e);
2875                }
2876
2877                /*
2878                 * Add shared application GID so applications can share some
2879                 * resources like shared libraries
2880                 */
2881                if (permGids == null) {
2882                    gids = new int[1];
2883                } else {
2884                    gids = new int[permGids.length + 1];
2885                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2886                }
2887                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2888            }
2889            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2890                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2891                        && mTopComponent != null
2892                        && app.processName.equals(mTopComponent.getPackageName())) {
2893                    uid = 0;
2894                }
2895                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2896                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2897                    uid = 0;
2898                }
2899            }
2900            int debugFlags = 0;
2901            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2902                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2903                // Also turn on CheckJNI for debuggable apps. It's quite
2904                // awkward to turn on otherwise.
2905                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2906            }
2907            // Run the app in safe mode if its manifest requests so or the
2908            // system is booted in safe mode.
2909            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2910                mSafeMode == true) {
2911                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2912            }
2913            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2914                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2915            }
2916            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2917                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2918            }
2919            if ("1".equals(SystemProperties.get("debug.assert"))) {
2920                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2921            }
2922
2923            String requiredAbi = app.info.cpuAbi;
2924            if (requiredAbi == null) {
2925                requiredAbi = Build.SUPPORTED_ABIS[0];
2926            }
2927
2928            // Start the process.  It will either succeed and return a result containing
2929            // the PID of the new process, or else throw a RuntimeException.
2930            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2931                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2932                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2933
2934            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2935            synchronized (bs) {
2936                if (bs.isOnBattery()) {
2937                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2938                }
2939            }
2940
2941            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2942                    UserHandle.getUserId(uid), startResult.pid, uid,
2943                    app.processName, hostingType,
2944                    hostingNameStr != null ? hostingNameStr : "");
2945
2946            if (app.persistent) {
2947                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2948            }
2949
2950            StringBuilder buf = mStringBuilder;
2951            buf.setLength(0);
2952            buf.append("Start proc ");
2953            buf.append(app.processName);
2954            buf.append(" for ");
2955            buf.append(hostingType);
2956            if (hostingNameStr != null) {
2957                buf.append(" ");
2958                buf.append(hostingNameStr);
2959            }
2960            buf.append(": pid=");
2961            buf.append(startResult.pid);
2962            buf.append(" uid=");
2963            buf.append(uid);
2964            buf.append(" gids={");
2965            if (gids != null) {
2966                for (int gi=0; gi<gids.length; gi++) {
2967                    if (gi != 0) buf.append(", ");
2968                    buf.append(gids[gi]);
2969
2970                }
2971            }
2972            buf.append("}");
2973            Slog.i(TAG, buf.toString());
2974            app.setPid(startResult.pid);
2975            app.usingWrapper = startResult.usingWrapper;
2976            app.removed = false;
2977            synchronized (mPidsSelfLocked) {
2978                this.mPidsSelfLocked.put(startResult.pid, app);
2979                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2980                msg.obj = app;
2981                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2982                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2983            }
2984            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2985                    app.processName, app.info.uid);
2986            if (app.isolated) {
2987                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2988            }
2989        } catch (RuntimeException e) {
2990            // XXX do better error recovery.
2991            app.setPid(0);
2992            Slog.e(TAG, "Failure starting process " + app.processName, e);
2993        }
2994    }
2995
2996    void updateUsageStats(ActivityRecord component, boolean resumed) {
2997        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2998        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2999        if (resumed) {
3000            mUsageStatsService.noteResumeComponent(component.realActivity);
3001            synchronized (stats) {
3002                stats.noteActivityResumedLocked(component.app.uid);
3003            }
3004        } else {
3005            mUsageStatsService.notePauseComponent(component.realActivity);
3006            synchronized (stats) {
3007                stats.noteActivityPausedLocked(component.app.uid);
3008            }
3009        }
3010    }
3011
3012    Intent getHomeIntent() {
3013        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3014        intent.setComponent(mTopComponent);
3015        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3016            intent.addCategory(Intent.CATEGORY_HOME);
3017        }
3018        return intent;
3019    }
3020
3021    boolean startHomeActivityLocked(int userId) {
3022        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3023                && mTopAction == null) {
3024            // We are running in factory test mode, but unable to find
3025            // the factory test app, so just sit around displaying the
3026            // error message and don't try to start anything.
3027            return false;
3028        }
3029        Intent intent = getHomeIntent();
3030        ActivityInfo aInfo =
3031            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3032        if (aInfo != null) {
3033            intent.setComponent(new ComponentName(
3034                    aInfo.applicationInfo.packageName, aInfo.name));
3035            // Don't do this if the home app is currently being
3036            // instrumented.
3037            aInfo = new ActivityInfo(aInfo);
3038            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3039            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3040                    aInfo.applicationInfo.uid, true);
3041            if (app == null || app.instrumentationClass == null) {
3042                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3043                mStackSupervisor.startHomeActivity(intent, aInfo);
3044            }
3045        }
3046
3047        return true;
3048    }
3049
3050    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3051        ActivityInfo ai = null;
3052        ComponentName comp = intent.getComponent();
3053        try {
3054            if (comp != null) {
3055                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3056            } else {
3057                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3058                        intent,
3059                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3060                            flags, userId);
3061
3062                if (info != null) {
3063                    ai = info.activityInfo;
3064                }
3065            }
3066        } catch (RemoteException e) {
3067            // ignore
3068        }
3069
3070        return ai;
3071    }
3072
3073    /**
3074     * Starts the "new version setup screen" if appropriate.
3075     */
3076    void startSetupActivityLocked() {
3077        // Only do this once per boot.
3078        if (mCheckedForSetup) {
3079            return;
3080        }
3081
3082        // We will show this screen if the current one is a different
3083        // version than the last one shown, and we are not running in
3084        // low-level factory test mode.
3085        final ContentResolver resolver = mContext.getContentResolver();
3086        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3087                Settings.Global.getInt(resolver,
3088                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3089            mCheckedForSetup = true;
3090
3091            // See if we should be showing the platform update setup UI.
3092            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3093            List<ResolveInfo> ris = mContext.getPackageManager()
3094                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3095
3096            // We don't allow third party apps to replace this.
3097            ResolveInfo ri = null;
3098            for (int i=0; ris != null && i<ris.size(); i++) {
3099                if ((ris.get(i).activityInfo.applicationInfo.flags
3100                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3101                    ri = ris.get(i);
3102                    break;
3103                }
3104            }
3105
3106            if (ri != null) {
3107                String vers = ri.activityInfo.metaData != null
3108                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3109                        : null;
3110                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3111                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3112                            Intent.METADATA_SETUP_VERSION);
3113                }
3114                String lastVers = Settings.Secure.getString(
3115                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3116                if (vers != null && !vers.equals(lastVers)) {
3117                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3118                    intent.setComponent(new ComponentName(
3119                            ri.activityInfo.packageName, ri.activityInfo.name));
3120                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3121                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3122                }
3123            }
3124        }
3125    }
3126
3127    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3128        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3129    }
3130
3131    void enforceNotIsolatedCaller(String caller) {
3132        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3133            throw new SecurityException("Isolated process not allowed to call " + caller);
3134        }
3135    }
3136
3137    @Override
3138    public int getFrontActivityScreenCompatMode() {
3139        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3140        synchronized (this) {
3141            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3142        }
3143    }
3144
3145    @Override
3146    public void setFrontActivityScreenCompatMode(int mode) {
3147        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3148                "setFrontActivityScreenCompatMode");
3149        synchronized (this) {
3150            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3151        }
3152    }
3153
3154    @Override
3155    public int getPackageScreenCompatMode(String packageName) {
3156        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3157        synchronized (this) {
3158            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3159        }
3160    }
3161
3162    @Override
3163    public void setPackageScreenCompatMode(String packageName, int mode) {
3164        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3165                "setPackageScreenCompatMode");
3166        synchronized (this) {
3167            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3168        }
3169    }
3170
3171    @Override
3172    public boolean getPackageAskScreenCompat(String packageName) {
3173        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3174        synchronized (this) {
3175            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3176        }
3177    }
3178
3179    @Override
3180    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3181        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3182                "setPackageAskScreenCompat");
3183        synchronized (this) {
3184            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3185        }
3186    }
3187
3188    private void dispatchProcessesChanged() {
3189        int N;
3190        synchronized (this) {
3191            N = mPendingProcessChanges.size();
3192            if (mActiveProcessChanges.length < N) {
3193                mActiveProcessChanges = new ProcessChangeItem[N];
3194            }
3195            mPendingProcessChanges.toArray(mActiveProcessChanges);
3196            mAvailProcessChanges.addAll(mPendingProcessChanges);
3197            mPendingProcessChanges.clear();
3198            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3199        }
3200
3201        int i = mProcessObservers.beginBroadcast();
3202        while (i > 0) {
3203            i--;
3204            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3205            if (observer != null) {
3206                try {
3207                    for (int j=0; j<N; j++) {
3208                        ProcessChangeItem item = mActiveProcessChanges[j];
3209                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3210                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3211                                    + item.pid + " uid=" + item.uid + ": "
3212                                    + item.foregroundActivities);
3213                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3214                                    item.foregroundActivities);
3215                        }
3216                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3217                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3218                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3219                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3220                        }
3221                    }
3222                } catch (RemoteException e) {
3223                }
3224            }
3225        }
3226        mProcessObservers.finishBroadcast();
3227    }
3228
3229    private void dispatchProcessDied(int pid, int uid) {
3230        int i = mProcessObservers.beginBroadcast();
3231        while (i > 0) {
3232            i--;
3233            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3234            if (observer != null) {
3235                try {
3236                    observer.onProcessDied(pid, uid);
3237                } catch (RemoteException e) {
3238                }
3239            }
3240        }
3241        mProcessObservers.finishBroadcast();
3242    }
3243
3244    final void doPendingActivityLaunchesLocked(boolean doResume) {
3245        final int N = mPendingActivityLaunches.size();
3246        if (N <= 0) {
3247            return;
3248        }
3249        for (int i=0; i<N; i++) {
3250            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3251            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3252                    doResume && i == (N-1), null);
3253        }
3254        mPendingActivityLaunches.clear();
3255    }
3256
3257    @Override
3258    public final int startActivity(IApplicationThread caller, String callingPackage,
3259            Intent intent, String resolvedType, IBinder resultTo,
3260            String resultWho, int requestCode, int startFlags,
3261            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3262        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3263                resultWho, requestCode,
3264                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3265    }
3266
3267    @Override
3268    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3269            Intent intent, String resolvedType, IBinder resultTo,
3270            String resultWho, int requestCode, int startFlags,
3271            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3272        enforceNotIsolatedCaller("startActivity");
3273        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3274                false, true, "startActivity", null);
3275        // TODO: Switch to user app stacks here.
3276        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3277                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3278                null, null, options, userId, null);
3279    }
3280
3281    @Override
3282    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3283            Intent intent, String resolvedType, IBinder resultTo,
3284            String resultWho, int requestCode, int startFlags, String profileFile,
3285            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3286        enforceNotIsolatedCaller("startActivityAndWait");
3287        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3288                false, true, "startActivityAndWait", null);
3289        WaitResult res = new WaitResult();
3290        // TODO: Switch to user app stacks here.
3291        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3292                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3293                res, null, options, UserHandle.getCallingUserId(), null);
3294        return res;
3295    }
3296
3297    @Override
3298    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3299            Intent intent, String resolvedType, IBinder resultTo,
3300            String resultWho, int requestCode, int startFlags, Configuration config,
3301            Bundle options, int userId) {
3302        enforceNotIsolatedCaller("startActivityWithConfig");
3303        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3304                false, true, "startActivityWithConfig", null);
3305        // TODO: Switch to user app stacks here.
3306        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3307                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3308                null, null, null, config, options, userId, null);
3309        return ret;
3310    }
3311
3312    @Override
3313    public int startActivityIntentSender(IApplicationThread caller,
3314            IntentSender intent, Intent fillInIntent, String resolvedType,
3315            IBinder resultTo, String resultWho, int requestCode,
3316            int flagsMask, int flagsValues, Bundle options) {
3317        enforceNotIsolatedCaller("startActivityIntentSender");
3318        // Refuse possible leaked file descriptors
3319        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3320            throw new IllegalArgumentException("File descriptors passed in Intent");
3321        }
3322
3323        IIntentSender sender = intent.getTarget();
3324        if (!(sender instanceof PendingIntentRecord)) {
3325            throw new IllegalArgumentException("Bad PendingIntent object");
3326        }
3327
3328        PendingIntentRecord pir = (PendingIntentRecord)sender;
3329
3330        synchronized (this) {
3331            // If this is coming from the currently resumed activity, it is
3332            // effectively saying that app switches are allowed at this point.
3333            final ActivityStack stack = getFocusedStack();
3334            if (stack.mResumedActivity != null &&
3335                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3336                mAppSwitchesAllowedTime = 0;
3337            }
3338        }
3339        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3340                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3341        return ret;
3342    }
3343
3344    @Override
3345    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3346            Intent intent, String resolvedType, IVoiceInteractionSession session,
3347            IVoiceInteractor interactor, int startFlags, String profileFile,
3348            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3349        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3350                != PackageManager.PERMISSION_GRANTED) {
3351            String msg = "Permission Denial: startVoiceActivity() from pid="
3352                    + Binder.getCallingPid()
3353                    + ", uid=" + Binder.getCallingUid()
3354                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3355            Slog.w(TAG, msg);
3356            throw new SecurityException(msg);
3357        }
3358        if (session == null || interactor == null) {
3359            throw new NullPointerException("null session or interactor");
3360        }
3361        userId = handleIncomingUser(callingPid, callingUid, userId,
3362                false, true, "startVoiceActivity", null);
3363        // TODO: Switch to user app stacks here.
3364        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3365                resolvedType, session, interactor, null, null, 0, startFlags,
3366                profileFile, profileFd, null, null, options, userId, null);
3367    }
3368
3369    @Override
3370    public boolean startNextMatchingActivity(IBinder callingActivity,
3371            Intent intent, Bundle options) {
3372        // Refuse possible leaked file descriptors
3373        if (intent != null && intent.hasFileDescriptors() == true) {
3374            throw new IllegalArgumentException("File descriptors passed in Intent");
3375        }
3376
3377        synchronized (this) {
3378            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3379            if (r == null) {
3380                ActivityOptions.abort(options);
3381                return false;
3382            }
3383            if (r.app == null || r.app.thread == null) {
3384                // The caller is not running...  d'oh!
3385                ActivityOptions.abort(options);
3386                return false;
3387            }
3388            intent = new Intent(intent);
3389            // The caller is not allowed to change the data.
3390            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3391            // And we are resetting to find the next component...
3392            intent.setComponent(null);
3393
3394            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3395
3396            ActivityInfo aInfo = null;
3397            try {
3398                List<ResolveInfo> resolves =
3399                    AppGlobals.getPackageManager().queryIntentActivities(
3400                            intent, r.resolvedType,
3401                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3402                            UserHandle.getCallingUserId());
3403
3404                // Look for the original activity in the list...
3405                final int N = resolves != null ? resolves.size() : 0;
3406                for (int i=0; i<N; i++) {
3407                    ResolveInfo rInfo = resolves.get(i);
3408                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3409                            && rInfo.activityInfo.name.equals(r.info.name)) {
3410                        // We found the current one...  the next matching is
3411                        // after it.
3412                        i++;
3413                        if (i<N) {
3414                            aInfo = resolves.get(i).activityInfo;
3415                        }
3416                        if (debug) {
3417                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3418                                    + "/" + r.info.name);
3419                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3420                                    + "/" + aInfo.name);
3421                        }
3422                        break;
3423                    }
3424                }
3425            } catch (RemoteException e) {
3426            }
3427
3428            if (aInfo == null) {
3429                // Nobody who is next!
3430                ActivityOptions.abort(options);
3431                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3432                return false;
3433            }
3434
3435            intent.setComponent(new ComponentName(
3436                    aInfo.applicationInfo.packageName, aInfo.name));
3437            intent.setFlags(intent.getFlags()&~(
3438                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3439                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3440                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3441                    Intent.FLAG_ACTIVITY_NEW_TASK));
3442
3443            // Okay now we need to start the new activity, replacing the
3444            // currently running activity.  This is a little tricky because
3445            // we want to start the new one as if the current one is finished,
3446            // but not finish the current one first so that there is no flicker.
3447            // And thus...
3448            final boolean wasFinishing = r.finishing;
3449            r.finishing = true;
3450
3451            // Propagate reply information over to the new activity.
3452            final ActivityRecord resultTo = r.resultTo;
3453            final String resultWho = r.resultWho;
3454            final int requestCode = r.requestCode;
3455            r.resultTo = null;
3456            if (resultTo != null) {
3457                resultTo.removeResultsLocked(r, resultWho, requestCode);
3458            }
3459
3460            final long origId = Binder.clearCallingIdentity();
3461            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3462                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3463                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3464                    options, false, null, null);
3465            Binder.restoreCallingIdentity(origId);
3466
3467            r.finishing = wasFinishing;
3468            if (res != ActivityManager.START_SUCCESS) {
3469                return false;
3470            }
3471            return true;
3472        }
3473    }
3474
3475    final int startActivityInPackage(int uid, String callingPackage,
3476            Intent intent, String resolvedType, IBinder resultTo,
3477            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3478                    IActivityContainer container) {
3479
3480        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3481                false, true, "startActivityInPackage", null);
3482
3483        // TODO: Switch to user app stacks here.
3484        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3485                null, null, resultTo, resultWho, requestCode, startFlags,
3486                null, null, null, null, options, userId, container);
3487        return ret;
3488    }
3489
3490    @Override
3491    public final int startActivities(IApplicationThread caller, String callingPackage,
3492            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3493            int userId) {
3494        enforceNotIsolatedCaller("startActivities");
3495        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3496                false, true, "startActivity", null);
3497        // TODO: Switch to user app stacks here.
3498        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3499                resolvedTypes, resultTo, options, userId);
3500        return ret;
3501    }
3502
3503    final int startActivitiesInPackage(int uid, String callingPackage,
3504            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3505            Bundle options, int userId) {
3506
3507        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3508                false, true, "startActivityInPackage", null);
3509        // TODO: Switch to user app stacks here.
3510        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3511                resultTo, options, userId);
3512        return ret;
3513    }
3514
3515    final void addRecentTaskLocked(TaskRecord task) {
3516        int N = mRecentTasks.size();
3517        // Quick case: check if the top-most recent task is the same.
3518        if (N > 0 && mRecentTasks.get(0) == task) {
3519            return;
3520        }
3521        // Another quick case: never add voice sessions.
3522        if (task.voiceSession != null) {
3523            return;
3524        }
3525        // Remove any existing entries that are the same kind of task.
3526        final Intent intent = task.intent;
3527        final boolean document = intent != null && intent.isDocument();
3528        for (int i=0; i<N; i++) {
3529            TaskRecord tr = mRecentTasks.get(i);
3530            if (task != tr) {
3531                if (task.userId != tr.userId) {
3532                    continue;
3533                }
3534                final Intent trIntent = tr.intent;
3535                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3536                    (intent == null || !intent.filterEquals(trIntent))) {
3537                    continue;
3538                }
3539                if (document || trIntent != null && trIntent.isDocument()) {
3540                    // Document tasks do not match other tasks.
3541                    continue;
3542                }
3543            }
3544
3545            // Either task and tr are the same or, their affinities match or their intents match
3546            // and neither of them is a document.
3547            tr.disposeThumbnail();
3548            mRecentTasks.remove(i);
3549            i--;
3550            N--;
3551            if (task.intent == null) {
3552                // If the new recent task we are adding is not fully
3553                // specified, then replace it with the existing recent task.
3554                task = tr;
3555            }
3556        }
3557        if (N >= MAX_RECENT_TASKS) {
3558            mRecentTasks.remove(N-1).disposeThumbnail();
3559        }
3560        mRecentTasks.add(0, task);
3561    }
3562
3563    @Override
3564    public void reportActivityFullyDrawn(IBinder token) {
3565        synchronized (this) {
3566            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3567            if (r == null) {
3568                return;
3569            }
3570            r.reportFullyDrawnLocked();
3571        }
3572    }
3573
3574    @Override
3575    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3576        synchronized (this) {
3577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3578            if (r == null) {
3579                return;
3580            }
3581            final long origId = Binder.clearCallingIdentity();
3582            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3583            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3584                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3585            if (config != null) {
3586                r.frozenBeforeDestroy = true;
3587                if (!updateConfigurationLocked(config, r, false, false)) {
3588                    mStackSupervisor.resumeTopActivitiesLocked();
3589                }
3590            }
3591            Binder.restoreCallingIdentity(origId);
3592        }
3593    }
3594
3595    @Override
3596    public int getRequestedOrientation(IBinder token) {
3597        synchronized (this) {
3598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3599            if (r == null) {
3600                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3601            }
3602            return mWindowManager.getAppOrientation(r.appToken);
3603        }
3604    }
3605
3606    /**
3607     * This is the internal entry point for handling Activity.finish().
3608     *
3609     * @param token The Binder token referencing the Activity we want to finish.
3610     * @param resultCode Result code, if any, from this Activity.
3611     * @param resultData Result data (Intent), if any, from this Activity.
3612     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3613     *            the root Activity in the task.
3614     *
3615     * @return Returns true if the activity successfully finished, or false if it is still running.
3616     */
3617    @Override
3618    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3619            boolean finishTask) {
3620        // Refuse possible leaked file descriptors
3621        if (resultData != null && resultData.hasFileDescriptors() == true) {
3622            throw new IllegalArgumentException("File descriptors passed in Intent");
3623        }
3624
3625        synchronized(this) {
3626            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3627            if (r == null) {
3628                return true;
3629            }
3630            // Keep track of the root activity of the task before we finish it
3631            TaskRecord tr = r.task;
3632            ActivityRecord rootR = tr.getRootActivity();
3633            if (mController != null) {
3634                // Find the first activity that is not finishing.
3635                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3636                if (next != null) {
3637                    // ask watcher if this is allowed
3638                    boolean resumeOK = true;
3639                    try {
3640                        resumeOK = mController.activityResuming(next.packageName);
3641                    } catch (RemoteException e) {
3642                        mController = null;
3643                        Watchdog.getInstance().setActivityController(null);
3644                    }
3645
3646                    if (!resumeOK) {
3647                        return false;
3648                    }
3649                }
3650            }
3651            final long origId = Binder.clearCallingIdentity();
3652            try {
3653                boolean res;
3654                if (finishTask && r == rootR) {
3655                    // If requested, remove the task that is associated to this activity only if it
3656                    // was the root activity in the task.  The result code and data is ignored because
3657                    // we don't support returning them across task boundaries.
3658                    res = removeTaskByIdLocked(tr.taskId, 0);
3659                } else {
3660                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3661                            resultData, "app-request", true);
3662                }
3663                return res;
3664            } finally {
3665                Binder.restoreCallingIdentity(origId);
3666            }
3667        }
3668    }
3669
3670    @Override
3671    public final void finishHeavyWeightApp() {
3672        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3673                != PackageManager.PERMISSION_GRANTED) {
3674            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3675                    + Binder.getCallingPid()
3676                    + ", uid=" + Binder.getCallingUid()
3677                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3678            Slog.w(TAG, msg);
3679            throw new SecurityException(msg);
3680        }
3681
3682        synchronized(this) {
3683            if (mHeavyWeightProcess == null) {
3684                return;
3685            }
3686
3687            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3688                    mHeavyWeightProcess.activities);
3689            for (int i=0; i<activities.size(); i++) {
3690                ActivityRecord r = activities.get(i);
3691                if (!r.finishing) {
3692                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3693                            null, "finish-heavy", true);
3694                }
3695            }
3696
3697            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3698                    mHeavyWeightProcess.userId, 0));
3699            mHeavyWeightProcess = null;
3700        }
3701    }
3702
3703    @Override
3704    public void crashApplication(int uid, int initialPid, String packageName,
3705            String message) {
3706        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3707                != PackageManager.PERMISSION_GRANTED) {
3708            String msg = "Permission Denial: crashApplication() from pid="
3709                    + Binder.getCallingPid()
3710                    + ", uid=" + Binder.getCallingUid()
3711                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3712            Slog.w(TAG, msg);
3713            throw new SecurityException(msg);
3714        }
3715
3716        synchronized(this) {
3717            ProcessRecord proc = null;
3718
3719            // Figure out which process to kill.  We don't trust that initialPid
3720            // still has any relation to current pids, so must scan through the
3721            // list.
3722            synchronized (mPidsSelfLocked) {
3723                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3724                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3725                    if (p.uid != uid) {
3726                        continue;
3727                    }
3728                    if (p.pid == initialPid) {
3729                        proc = p;
3730                        break;
3731                    }
3732                    if (p.pkgList.containsKey(packageName)) {
3733                        proc = p;
3734                    }
3735                }
3736            }
3737
3738            if (proc == null) {
3739                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3740                        + " initialPid=" + initialPid
3741                        + " packageName=" + packageName);
3742                return;
3743            }
3744
3745            if (proc.thread != null) {
3746                if (proc.pid == Process.myPid()) {
3747                    Log.w(TAG, "crashApplication: trying to crash self!");
3748                    return;
3749                }
3750                long ident = Binder.clearCallingIdentity();
3751                try {
3752                    proc.thread.scheduleCrash(message);
3753                } catch (RemoteException e) {
3754                }
3755                Binder.restoreCallingIdentity(ident);
3756            }
3757        }
3758    }
3759
3760    @Override
3761    public final void finishSubActivity(IBinder token, String resultWho,
3762            int requestCode) {
3763        synchronized(this) {
3764            final long origId = Binder.clearCallingIdentity();
3765            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3766            if (r != null) {
3767                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3768            }
3769            Binder.restoreCallingIdentity(origId);
3770        }
3771    }
3772
3773    @Override
3774    public boolean finishActivityAffinity(IBinder token) {
3775        synchronized(this) {
3776            final long origId = Binder.clearCallingIdentity();
3777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3778            boolean res = false;
3779            if (r != null) {
3780                res = r.task.stack.finishActivityAffinityLocked(r);
3781            }
3782            Binder.restoreCallingIdentity(origId);
3783            return res;
3784        }
3785    }
3786
3787    @Override
3788    public boolean willActivityBeVisible(IBinder token) {
3789        synchronized(this) {
3790            ActivityStack stack = ActivityRecord.getStackLocked(token);
3791            if (stack != null) {
3792                return stack.willActivityBeVisibleLocked(token);
3793            }
3794            return false;
3795        }
3796    }
3797
3798    @Override
3799    public void overridePendingTransition(IBinder token, String packageName,
3800            int enterAnim, int exitAnim) {
3801        synchronized(this) {
3802            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3803            if (self == null) {
3804                return;
3805            }
3806
3807            final long origId = Binder.clearCallingIdentity();
3808
3809            if (self.state == ActivityState.RESUMED
3810                    || self.state == ActivityState.PAUSING) {
3811                mWindowManager.overridePendingAppTransition(packageName,
3812                        enterAnim, exitAnim, null);
3813            }
3814
3815            Binder.restoreCallingIdentity(origId);
3816        }
3817    }
3818
3819    /**
3820     * Main function for removing an existing process from the activity manager
3821     * as a result of that process going away.  Clears out all connections
3822     * to the process.
3823     */
3824    private final void handleAppDiedLocked(ProcessRecord app,
3825            boolean restarting, boolean allowRestart) {
3826        int pid = app.pid;
3827        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3828        if (!restarting) {
3829            removeLruProcessLocked(app);
3830            if (pid > 0) {
3831                ProcessList.remove(pid);
3832            }
3833        }
3834
3835        if (mProfileProc == app) {
3836            clearProfilerLocked();
3837        }
3838
3839        // Remove this application's activities from active lists.
3840        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3841
3842        app.activities.clear();
3843
3844        if (app.instrumentationClass != null) {
3845            Slog.w(TAG, "Crash of app " + app.processName
3846                  + " running instrumentation " + app.instrumentationClass);
3847            Bundle info = new Bundle();
3848            info.putString("shortMsg", "Process crashed.");
3849            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3850        }
3851
3852        if (!restarting) {
3853            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3854                // If there was nothing to resume, and we are not already
3855                // restarting this process, but there is a visible activity that
3856                // is hosted by the process...  then make sure all visible
3857                // activities are running, taking care of restarting this
3858                // process.
3859                if (hasVisibleActivities) {
3860                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3861                }
3862            }
3863        }
3864    }
3865
3866    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3867        IBinder threadBinder = thread.asBinder();
3868        // Find the application record.
3869        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3870            ProcessRecord rec = mLruProcesses.get(i);
3871            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3872                return i;
3873            }
3874        }
3875        return -1;
3876    }
3877
3878    final ProcessRecord getRecordForAppLocked(
3879            IApplicationThread thread) {
3880        if (thread == null) {
3881            return null;
3882        }
3883
3884        int appIndex = getLRURecordIndexForAppLocked(thread);
3885        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3886    }
3887
3888    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3889        // If there are no longer any background processes running,
3890        // and the app that died was not running instrumentation,
3891        // then tell everyone we are now low on memory.
3892        boolean haveBg = false;
3893        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3894            ProcessRecord rec = mLruProcesses.get(i);
3895            if (rec.thread != null
3896                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3897                haveBg = true;
3898                break;
3899            }
3900        }
3901
3902        if (!haveBg) {
3903            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3904            if (doReport) {
3905                long now = SystemClock.uptimeMillis();
3906                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3907                    doReport = false;
3908                } else {
3909                    mLastMemUsageReportTime = now;
3910                }
3911            }
3912            final ArrayList<ProcessMemInfo> memInfos
3913                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3914            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3915            long now = SystemClock.uptimeMillis();
3916            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3917                ProcessRecord rec = mLruProcesses.get(i);
3918                if (rec == dyingProc || rec.thread == null) {
3919                    continue;
3920                }
3921                if (doReport) {
3922                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3923                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3924                }
3925                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3926                    // The low memory report is overriding any current
3927                    // state for a GC request.  Make sure to do
3928                    // heavy/important/visible/foreground processes first.
3929                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3930                        rec.lastRequestedGc = 0;
3931                    } else {
3932                        rec.lastRequestedGc = rec.lastLowMemory;
3933                    }
3934                    rec.reportLowMemory = true;
3935                    rec.lastLowMemory = now;
3936                    mProcessesToGc.remove(rec);
3937                    addProcessToGcListLocked(rec);
3938                }
3939            }
3940            if (doReport) {
3941                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3942                mHandler.sendMessage(msg);
3943            }
3944            scheduleAppGcsLocked();
3945        }
3946    }
3947
3948    final void appDiedLocked(ProcessRecord app, int pid,
3949            IApplicationThread thread) {
3950
3951        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3952        synchronized (stats) {
3953            stats.noteProcessDiedLocked(app.info.uid, pid);
3954        }
3955
3956        // Clean up already done if the process has been re-started.
3957        if (app.pid == pid && app.thread != null &&
3958                app.thread.asBinder() == thread.asBinder()) {
3959            boolean doLowMem = app.instrumentationClass == null;
3960            boolean doOomAdj = doLowMem;
3961            if (!app.killedByAm) {
3962                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3963                        + ") has died.");
3964                mAllowLowerMemLevel = true;
3965            } else {
3966                // Note that we always want to do oom adj to update our state with the
3967                // new number of procs.
3968                mAllowLowerMemLevel = false;
3969                doLowMem = false;
3970            }
3971            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3972            if (DEBUG_CLEANUP) Slog.v(
3973                TAG, "Dying app: " + app + ", pid: " + pid
3974                + ", thread: " + thread.asBinder());
3975            handleAppDiedLocked(app, false, true);
3976
3977            if (doOomAdj) {
3978                updateOomAdjLocked();
3979            }
3980            if (doLowMem) {
3981                doLowMemReportIfNeededLocked(app);
3982            }
3983        } else if (app.pid != pid) {
3984            // A new process has already been started.
3985            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3986                    + ") has died and restarted (pid " + app.pid + ").");
3987            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3988        } else if (DEBUG_PROCESSES) {
3989            Slog.d(TAG, "Received spurious death notification for thread "
3990                    + thread.asBinder());
3991        }
3992    }
3993
3994    /**
3995     * If a stack trace dump file is configured, dump process stack traces.
3996     * @param clearTraces causes the dump file to be erased prior to the new
3997     *    traces being written, if true; when false, the new traces will be
3998     *    appended to any existing file content.
3999     * @param firstPids of dalvik VM processes to dump stack traces for first
4000     * @param lastPids of dalvik VM processes to dump stack traces for last
4001     * @param nativeProcs optional list of native process names to dump stack crawls
4002     * @return file containing stack traces, or null if no dump file is configured
4003     */
4004    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4005            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4006        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4007        if (tracesPath == null || tracesPath.length() == 0) {
4008            return null;
4009        }
4010
4011        File tracesFile = new File(tracesPath);
4012        try {
4013            File tracesDir = tracesFile.getParentFile();
4014            if (!tracesDir.exists()) {
4015                tracesFile.mkdirs();
4016                if (!SELinux.restorecon(tracesDir)) {
4017                    return null;
4018                }
4019            }
4020            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4021
4022            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4023            tracesFile.createNewFile();
4024            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4025        } catch (IOException e) {
4026            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4027            return null;
4028        }
4029
4030        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4031        return tracesFile;
4032    }
4033
4034    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4035            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4036        // Use a FileObserver to detect when traces finish writing.
4037        // The order of traces is considered important to maintain for legibility.
4038        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4039            @Override
4040            public synchronized void onEvent(int event, String path) { notify(); }
4041        };
4042
4043        try {
4044            observer.startWatching();
4045
4046            // First collect all of the stacks of the most important pids.
4047            if (firstPids != null) {
4048                try {
4049                    int num = firstPids.size();
4050                    for (int i = 0; i < num; i++) {
4051                        synchronized (observer) {
4052                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4053                            observer.wait(200);  // Wait for write-close, give up after 200msec
4054                        }
4055                    }
4056                } catch (InterruptedException e) {
4057                    Log.wtf(TAG, e);
4058                }
4059            }
4060
4061            // Next collect the stacks of the native pids
4062            if (nativeProcs != null) {
4063                int[] pids = Process.getPidsForCommands(nativeProcs);
4064                if (pids != null) {
4065                    for (int pid : pids) {
4066                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4067                    }
4068                }
4069            }
4070
4071            // Lastly, measure CPU usage.
4072            if (processCpuTracker != null) {
4073                processCpuTracker.init();
4074                System.gc();
4075                processCpuTracker.update();
4076                try {
4077                    synchronized (processCpuTracker) {
4078                        processCpuTracker.wait(500); // measure over 1/2 second.
4079                    }
4080                } catch (InterruptedException e) {
4081                }
4082                processCpuTracker.update();
4083
4084                // We'll take the stack crawls of just the top apps using CPU.
4085                final int N = processCpuTracker.countWorkingStats();
4086                int numProcs = 0;
4087                for (int i=0; i<N && numProcs<5; i++) {
4088                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4089                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4090                        numProcs++;
4091                        try {
4092                            synchronized (observer) {
4093                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4094                                observer.wait(200);  // Wait for write-close, give up after 200msec
4095                            }
4096                        } catch (InterruptedException e) {
4097                            Log.wtf(TAG, e);
4098                        }
4099
4100                    }
4101                }
4102            }
4103        } finally {
4104            observer.stopWatching();
4105        }
4106    }
4107
4108    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4109        if (true || IS_USER_BUILD) {
4110            return;
4111        }
4112        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4113        if (tracesPath == null || tracesPath.length() == 0) {
4114            return;
4115        }
4116
4117        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4118        StrictMode.allowThreadDiskWrites();
4119        try {
4120            final File tracesFile = new File(tracesPath);
4121            final File tracesDir = tracesFile.getParentFile();
4122            final File tracesTmp = new File(tracesDir, "__tmp__");
4123            try {
4124                if (!tracesDir.exists()) {
4125                    tracesFile.mkdirs();
4126                    if (!SELinux.restorecon(tracesDir.getPath())) {
4127                        return;
4128                    }
4129                }
4130                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4131
4132                if (tracesFile.exists()) {
4133                    tracesTmp.delete();
4134                    tracesFile.renameTo(tracesTmp);
4135                }
4136                StringBuilder sb = new StringBuilder();
4137                Time tobj = new Time();
4138                tobj.set(System.currentTimeMillis());
4139                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4140                sb.append(": ");
4141                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4142                sb.append(" since ");
4143                sb.append(msg);
4144                FileOutputStream fos = new FileOutputStream(tracesFile);
4145                fos.write(sb.toString().getBytes());
4146                if (app == null) {
4147                    fos.write("\n*** No application process!".getBytes());
4148                }
4149                fos.close();
4150                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4151            } catch (IOException e) {
4152                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4153                return;
4154            }
4155
4156            if (app != null) {
4157                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4158                firstPids.add(app.pid);
4159                dumpStackTraces(tracesPath, firstPids, null, null, null);
4160            }
4161
4162            File lastTracesFile = null;
4163            File curTracesFile = null;
4164            for (int i=9; i>=0; i--) {
4165                String name = String.format(Locale.US, "slow%02d.txt", i);
4166                curTracesFile = new File(tracesDir, name);
4167                if (curTracesFile.exists()) {
4168                    if (lastTracesFile != null) {
4169                        curTracesFile.renameTo(lastTracesFile);
4170                    } else {
4171                        curTracesFile.delete();
4172                    }
4173                }
4174                lastTracesFile = curTracesFile;
4175            }
4176            tracesFile.renameTo(curTracesFile);
4177            if (tracesTmp.exists()) {
4178                tracesTmp.renameTo(tracesFile);
4179            }
4180        } finally {
4181            StrictMode.setThreadPolicy(oldPolicy);
4182        }
4183    }
4184
4185    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4186            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4187        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4188        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4189
4190        if (mController != null) {
4191            try {
4192                // 0 == continue, -1 = kill process immediately
4193                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4194                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4195            } catch (RemoteException e) {
4196                mController = null;
4197                Watchdog.getInstance().setActivityController(null);
4198            }
4199        }
4200
4201        long anrTime = SystemClock.uptimeMillis();
4202        if (MONITOR_CPU_USAGE) {
4203            updateCpuStatsNow();
4204        }
4205
4206        synchronized (this) {
4207            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4208            if (mShuttingDown) {
4209                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4210                return;
4211            } else if (app.notResponding) {
4212                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4213                return;
4214            } else if (app.crashing) {
4215                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4216                return;
4217            }
4218
4219            // In case we come through here for the same app before completing
4220            // this one, mark as anring now so we will bail out.
4221            app.notResponding = true;
4222
4223            // Log the ANR to the event log.
4224            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4225                    app.processName, app.info.flags, annotation);
4226
4227            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4228            firstPids.add(app.pid);
4229
4230            int parentPid = app.pid;
4231            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4232            if (parentPid != app.pid) firstPids.add(parentPid);
4233
4234            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4235
4236            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4237                ProcessRecord r = mLruProcesses.get(i);
4238                if (r != null && r.thread != null) {
4239                    int pid = r.pid;
4240                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4241                        if (r.persistent) {
4242                            firstPids.add(pid);
4243                        } else {
4244                            lastPids.put(pid, Boolean.TRUE);
4245                        }
4246                    }
4247                }
4248            }
4249        }
4250
4251        // Log the ANR to the main log.
4252        StringBuilder info = new StringBuilder();
4253        info.setLength(0);
4254        info.append("ANR in ").append(app.processName);
4255        if (activity != null && activity.shortComponentName != null) {
4256            info.append(" (").append(activity.shortComponentName).append(")");
4257        }
4258        info.append("\n");
4259        info.append("PID: ").append(app.pid).append("\n");
4260        if (annotation != null) {
4261            info.append("Reason: ").append(annotation).append("\n");
4262        }
4263        if (parent != null && parent != activity) {
4264            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4265        }
4266
4267        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4268
4269        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4270                NATIVE_STACKS_OF_INTEREST);
4271
4272        String cpuInfo = null;
4273        if (MONITOR_CPU_USAGE) {
4274            updateCpuStatsNow();
4275            synchronized (mProcessCpuThread) {
4276                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4277            }
4278            info.append(processCpuTracker.printCurrentLoad());
4279            info.append(cpuInfo);
4280        }
4281
4282        info.append(processCpuTracker.printCurrentState(anrTime));
4283
4284        Slog.e(TAG, info.toString());
4285        if (tracesFile == null) {
4286            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4287            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4288        }
4289
4290        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4291                cpuInfo, tracesFile, null);
4292
4293        if (mController != null) {
4294            try {
4295                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4296                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4297                if (res != 0) {
4298                    if (res < 0 && app.pid != MY_PID) {
4299                        Process.killProcess(app.pid);
4300                    } else {
4301                        synchronized (this) {
4302                            mServices.scheduleServiceTimeoutLocked(app);
4303                        }
4304                    }
4305                    return;
4306                }
4307            } catch (RemoteException e) {
4308                mController = null;
4309                Watchdog.getInstance().setActivityController(null);
4310            }
4311        }
4312
4313        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4314        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4315                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4316
4317        synchronized (this) {
4318            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4319                killUnneededProcessLocked(app, "background ANR");
4320                return;
4321            }
4322
4323            // Set the app's notResponding state, and look up the errorReportReceiver
4324            makeAppNotRespondingLocked(app,
4325                    activity != null ? activity.shortComponentName : null,
4326                    annotation != null ? "ANR " + annotation : "ANR",
4327                    info.toString());
4328
4329            // Bring up the infamous App Not Responding dialog
4330            Message msg = Message.obtain();
4331            HashMap<String, Object> map = new HashMap<String, Object>();
4332            msg.what = SHOW_NOT_RESPONDING_MSG;
4333            msg.obj = map;
4334            msg.arg1 = aboveSystem ? 1 : 0;
4335            map.put("app", app);
4336            if (activity != null) {
4337                map.put("activity", activity);
4338            }
4339
4340            mHandler.sendMessage(msg);
4341        }
4342    }
4343
4344    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4345        if (!mLaunchWarningShown) {
4346            mLaunchWarningShown = true;
4347            mHandler.post(new Runnable() {
4348                @Override
4349                public void run() {
4350                    synchronized (ActivityManagerService.this) {
4351                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4352                        d.show();
4353                        mHandler.postDelayed(new Runnable() {
4354                            @Override
4355                            public void run() {
4356                                synchronized (ActivityManagerService.this) {
4357                                    d.dismiss();
4358                                    mLaunchWarningShown = false;
4359                                }
4360                            }
4361                        }, 4000);
4362                    }
4363                }
4364            });
4365        }
4366    }
4367
4368    @Override
4369    public boolean clearApplicationUserData(final String packageName,
4370            final IPackageDataObserver observer, int userId) {
4371        enforceNotIsolatedCaller("clearApplicationUserData");
4372        int uid = Binder.getCallingUid();
4373        int pid = Binder.getCallingPid();
4374        userId = handleIncomingUser(pid, uid,
4375                userId, false, true, "clearApplicationUserData", null);
4376        long callingId = Binder.clearCallingIdentity();
4377        try {
4378            IPackageManager pm = AppGlobals.getPackageManager();
4379            int pkgUid = -1;
4380            synchronized(this) {
4381                try {
4382                    pkgUid = pm.getPackageUid(packageName, userId);
4383                } catch (RemoteException e) {
4384                }
4385                if (pkgUid == -1) {
4386                    Slog.w(TAG, "Invalid packageName: " + packageName);
4387                    if (observer != null) {
4388                        try {
4389                            observer.onRemoveCompleted(packageName, false);
4390                        } catch (RemoteException e) {
4391                            Slog.i(TAG, "Observer no longer exists.");
4392                        }
4393                    }
4394                    return false;
4395                }
4396                if (uid == pkgUid || checkComponentPermission(
4397                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4398                        pid, uid, -1, true)
4399                        == PackageManager.PERMISSION_GRANTED) {
4400                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4401                } else {
4402                    throw new SecurityException("PID " + pid + " does not have permission "
4403                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4404                                    + " of package " + packageName);
4405                }
4406            }
4407
4408            try {
4409                // Clear application user data
4410                pm.clearApplicationUserData(packageName, observer, userId);
4411
4412                // Remove all permissions granted from/to this package
4413                removeUriPermissionsForPackageLocked(packageName, userId, true);
4414
4415                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4416                        Uri.fromParts("package", packageName, null));
4417                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4418                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4419                        null, null, 0, null, null, null, false, false, userId);
4420            } catch (RemoteException e) {
4421            }
4422        } finally {
4423            Binder.restoreCallingIdentity(callingId);
4424        }
4425        return true;
4426    }
4427
4428    @Override
4429    public void killBackgroundProcesses(final String packageName, int userId) {
4430        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4431                != PackageManager.PERMISSION_GRANTED &&
4432                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4433                        != PackageManager.PERMISSION_GRANTED) {
4434            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4435                    + Binder.getCallingPid()
4436                    + ", uid=" + Binder.getCallingUid()
4437                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4438            Slog.w(TAG, msg);
4439            throw new SecurityException(msg);
4440        }
4441
4442        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4443                userId, true, true, "killBackgroundProcesses", null);
4444        long callingId = Binder.clearCallingIdentity();
4445        try {
4446            IPackageManager pm = AppGlobals.getPackageManager();
4447            synchronized(this) {
4448                int appId = -1;
4449                try {
4450                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4451                } catch (RemoteException e) {
4452                }
4453                if (appId == -1) {
4454                    Slog.w(TAG, "Invalid packageName: " + packageName);
4455                    return;
4456                }
4457                killPackageProcessesLocked(packageName, appId, userId,
4458                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4459            }
4460        } finally {
4461            Binder.restoreCallingIdentity(callingId);
4462        }
4463    }
4464
4465    @Override
4466    public void killAllBackgroundProcesses() {
4467        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4468                != PackageManager.PERMISSION_GRANTED) {
4469            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4470                    + Binder.getCallingPid()
4471                    + ", uid=" + Binder.getCallingUid()
4472                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4473            Slog.w(TAG, msg);
4474            throw new SecurityException(msg);
4475        }
4476
4477        long callingId = Binder.clearCallingIdentity();
4478        try {
4479            synchronized(this) {
4480                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4481                final int NP = mProcessNames.getMap().size();
4482                for (int ip=0; ip<NP; ip++) {
4483                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4484                    final int NA = apps.size();
4485                    for (int ia=0; ia<NA; ia++) {
4486                        ProcessRecord app = apps.valueAt(ia);
4487                        if (app.persistent) {
4488                            // we don't kill persistent processes
4489                            continue;
4490                        }
4491                        if (app.removed) {
4492                            procs.add(app);
4493                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4494                            app.removed = true;
4495                            procs.add(app);
4496                        }
4497                    }
4498                }
4499
4500                int N = procs.size();
4501                for (int i=0; i<N; i++) {
4502                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4503                }
4504                mAllowLowerMemLevel = true;
4505                updateOomAdjLocked();
4506                doLowMemReportIfNeededLocked(null);
4507            }
4508        } finally {
4509            Binder.restoreCallingIdentity(callingId);
4510        }
4511    }
4512
4513    @Override
4514    public void forceStopPackage(final String packageName, int userId) {
4515        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4516                != PackageManager.PERMISSION_GRANTED) {
4517            String msg = "Permission Denial: forceStopPackage() from pid="
4518                    + Binder.getCallingPid()
4519                    + ", uid=" + Binder.getCallingUid()
4520                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4521            Slog.w(TAG, msg);
4522            throw new SecurityException(msg);
4523        }
4524        final int callingPid = Binder.getCallingPid();
4525        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4526                userId, true, true, "forceStopPackage", null);
4527        long callingId = Binder.clearCallingIdentity();
4528        try {
4529            IPackageManager pm = AppGlobals.getPackageManager();
4530            synchronized(this) {
4531                int[] users = userId == UserHandle.USER_ALL
4532                        ? getUsersLocked() : new int[] { userId };
4533                for (int user : users) {
4534                    int pkgUid = -1;
4535                    try {
4536                        pkgUid = pm.getPackageUid(packageName, user);
4537                    } catch (RemoteException e) {
4538                    }
4539                    if (pkgUid == -1) {
4540                        Slog.w(TAG, "Invalid packageName: " + packageName);
4541                        continue;
4542                    }
4543                    try {
4544                        pm.setPackageStoppedState(packageName, true, user);
4545                    } catch (RemoteException e) {
4546                    } catch (IllegalArgumentException e) {
4547                        Slog.w(TAG, "Failed trying to unstop package "
4548                                + packageName + ": " + e);
4549                    }
4550                    if (isUserRunningLocked(user, false)) {
4551                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4552                    }
4553                }
4554            }
4555        } finally {
4556            Binder.restoreCallingIdentity(callingId);
4557        }
4558    }
4559
4560    /*
4561     * The pkg name and app id have to be specified.
4562     */
4563    @Override
4564    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4565        if (pkg == null) {
4566            return;
4567        }
4568        // Make sure the uid is valid.
4569        if (appid < 0) {
4570            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4571            return;
4572        }
4573        int callerUid = Binder.getCallingUid();
4574        // Only the system server can kill an application
4575        if (callerUid == Process.SYSTEM_UID) {
4576            // Post an aysnc message to kill the application
4577            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4578            msg.arg1 = appid;
4579            msg.arg2 = 0;
4580            Bundle bundle = new Bundle();
4581            bundle.putString("pkg", pkg);
4582            bundle.putString("reason", reason);
4583            msg.obj = bundle;
4584            mHandler.sendMessage(msg);
4585        } else {
4586            throw new SecurityException(callerUid + " cannot kill pkg: " +
4587                    pkg);
4588        }
4589    }
4590
4591    @Override
4592    public void closeSystemDialogs(String reason) {
4593        enforceNotIsolatedCaller("closeSystemDialogs");
4594
4595        final int pid = Binder.getCallingPid();
4596        final int uid = Binder.getCallingUid();
4597        final long origId = Binder.clearCallingIdentity();
4598        try {
4599            synchronized (this) {
4600                // Only allow this from foreground processes, so that background
4601                // applications can't abuse it to prevent system UI from being shown.
4602                if (uid >= Process.FIRST_APPLICATION_UID) {
4603                    ProcessRecord proc;
4604                    synchronized (mPidsSelfLocked) {
4605                        proc = mPidsSelfLocked.get(pid);
4606                    }
4607                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4608                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4609                                + " from background process " + proc);
4610                        return;
4611                    }
4612                }
4613                closeSystemDialogsLocked(reason);
4614            }
4615        } finally {
4616            Binder.restoreCallingIdentity(origId);
4617        }
4618    }
4619
4620    void closeSystemDialogsLocked(String reason) {
4621        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4622        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4623                | Intent.FLAG_RECEIVER_FOREGROUND);
4624        if (reason != null) {
4625            intent.putExtra("reason", reason);
4626        }
4627        mWindowManager.closeSystemDialogs(reason);
4628
4629        mStackSupervisor.closeSystemDialogsLocked();
4630
4631        broadcastIntentLocked(null, null, intent, null,
4632                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4633                Process.SYSTEM_UID, UserHandle.USER_ALL);
4634    }
4635
4636    @Override
4637    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4638        enforceNotIsolatedCaller("getProcessMemoryInfo");
4639        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4640        for (int i=pids.length-1; i>=0; i--) {
4641            ProcessRecord proc;
4642            int oomAdj;
4643            synchronized (this) {
4644                synchronized (mPidsSelfLocked) {
4645                    proc = mPidsSelfLocked.get(pids[i]);
4646                    oomAdj = proc != null ? proc.setAdj : 0;
4647                }
4648            }
4649            infos[i] = new Debug.MemoryInfo();
4650            Debug.getMemoryInfo(pids[i], infos[i]);
4651            if (proc != null) {
4652                synchronized (this) {
4653                    if (proc.thread != null && proc.setAdj == oomAdj) {
4654                        // Record this for posterity if the process has been stable.
4655                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4656                                infos[i].getTotalUss(), false, proc.pkgList);
4657                    }
4658                }
4659            }
4660        }
4661        return infos;
4662    }
4663
4664    @Override
4665    public long[] getProcessPss(int[] pids) {
4666        enforceNotIsolatedCaller("getProcessPss");
4667        long[] pss = new long[pids.length];
4668        for (int i=pids.length-1; i>=0; i--) {
4669            ProcessRecord proc;
4670            int oomAdj;
4671            synchronized (this) {
4672                synchronized (mPidsSelfLocked) {
4673                    proc = mPidsSelfLocked.get(pids[i]);
4674                    oomAdj = proc != null ? proc.setAdj : 0;
4675                }
4676            }
4677            long[] tmpUss = new long[1];
4678            pss[i] = Debug.getPss(pids[i], tmpUss);
4679            if (proc != null) {
4680                synchronized (this) {
4681                    if (proc.thread != null && proc.setAdj == oomAdj) {
4682                        // Record this for posterity if the process has been stable.
4683                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4684                    }
4685                }
4686            }
4687        }
4688        return pss;
4689    }
4690
4691    @Override
4692    public void killApplicationProcess(String processName, int uid) {
4693        if (processName == null) {
4694            return;
4695        }
4696
4697        int callerUid = Binder.getCallingUid();
4698        // Only the system server can kill an application
4699        if (callerUid == Process.SYSTEM_UID) {
4700            synchronized (this) {
4701                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4702                if (app != null && app.thread != null) {
4703                    try {
4704                        app.thread.scheduleSuicide();
4705                    } catch (RemoteException e) {
4706                        // If the other end already died, then our work here is done.
4707                    }
4708                } else {
4709                    Slog.w(TAG, "Process/uid not found attempting kill of "
4710                            + processName + " / " + uid);
4711                }
4712            }
4713        } else {
4714            throw new SecurityException(callerUid + " cannot kill app process: " +
4715                    processName);
4716        }
4717    }
4718
4719    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4720        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4721                false, true, false, false, UserHandle.getUserId(uid), reason);
4722        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4723                Uri.fromParts("package", packageName, null));
4724        if (!mProcessesReady) {
4725            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4726                    | Intent.FLAG_RECEIVER_FOREGROUND);
4727        }
4728        intent.putExtra(Intent.EXTRA_UID, uid);
4729        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4730        broadcastIntentLocked(null, null, intent,
4731                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4732                false, false,
4733                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4734    }
4735
4736    private void forceStopUserLocked(int userId, String reason) {
4737        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4738        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4739        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4740                | Intent.FLAG_RECEIVER_FOREGROUND);
4741        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4742        broadcastIntentLocked(null, null, intent,
4743                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4744                false, false,
4745                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4746    }
4747
4748    private final boolean killPackageProcessesLocked(String packageName, int appId,
4749            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4750            boolean doit, boolean evenPersistent, String reason) {
4751        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4752
4753        // Remove all processes this package may have touched: all with the
4754        // same UID (except for the system or root user), and all whose name
4755        // matches the package name.
4756        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4757        final int NP = mProcessNames.getMap().size();
4758        for (int ip=0; ip<NP; ip++) {
4759            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4760            final int NA = apps.size();
4761            for (int ia=0; ia<NA; ia++) {
4762                ProcessRecord app = apps.valueAt(ia);
4763                if (app.persistent && !evenPersistent) {
4764                    // we don't kill persistent processes
4765                    continue;
4766                }
4767                if (app.removed) {
4768                    if (doit) {
4769                        procs.add(app);
4770                    }
4771                    continue;
4772                }
4773
4774                // Skip process if it doesn't meet our oom adj requirement.
4775                if (app.setAdj < minOomAdj) {
4776                    continue;
4777                }
4778
4779                // If no package is specified, we call all processes under the
4780                // give user id.
4781                if (packageName == null) {
4782                    if (app.userId != userId) {
4783                        continue;
4784                    }
4785                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4786                        continue;
4787                    }
4788                // Package has been specified, we want to hit all processes
4789                // that match it.  We need to qualify this by the processes
4790                // that are running under the specified app and user ID.
4791                } else {
4792                    if (UserHandle.getAppId(app.uid) != appId) {
4793                        continue;
4794                    }
4795                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4796                        continue;
4797                    }
4798                    if (!app.pkgList.containsKey(packageName)) {
4799                        continue;
4800                    }
4801                }
4802
4803                // Process has passed all conditions, kill it!
4804                if (!doit) {
4805                    return true;
4806                }
4807                app.removed = true;
4808                procs.add(app);
4809            }
4810        }
4811
4812        int N = procs.size();
4813        for (int i=0; i<N; i++) {
4814            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4815        }
4816        updateOomAdjLocked();
4817        return N > 0;
4818    }
4819
4820    private final boolean forceStopPackageLocked(String name, int appId,
4821            boolean callerWillRestart, boolean purgeCache, boolean doit,
4822            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4823        int i;
4824        int N;
4825
4826        if (userId == UserHandle.USER_ALL && name == null) {
4827            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4828        }
4829
4830        if (appId < 0 && name != null) {
4831            try {
4832                appId = UserHandle.getAppId(
4833                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4834            } catch (RemoteException e) {
4835            }
4836        }
4837
4838        if (doit) {
4839            if (name != null) {
4840                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4841                        + " user=" + userId + ": " + reason);
4842            } else {
4843                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4844            }
4845
4846            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4847            for (int ip=pmap.size()-1; ip>=0; ip--) {
4848                SparseArray<Long> ba = pmap.valueAt(ip);
4849                for (i=ba.size()-1; i>=0; i--) {
4850                    boolean remove = false;
4851                    final int entUid = ba.keyAt(i);
4852                    if (name != null) {
4853                        if (userId == UserHandle.USER_ALL) {
4854                            if (UserHandle.getAppId(entUid) == appId) {
4855                                remove = true;
4856                            }
4857                        } else {
4858                            if (entUid == UserHandle.getUid(userId, appId)) {
4859                                remove = true;
4860                            }
4861                        }
4862                    } else if (UserHandle.getUserId(entUid) == userId) {
4863                        remove = true;
4864                    }
4865                    if (remove) {
4866                        ba.removeAt(i);
4867                    }
4868                }
4869                if (ba.size() == 0) {
4870                    pmap.removeAt(ip);
4871                }
4872            }
4873        }
4874
4875        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4876                -100, callerWillRestart, true, doit, evenPersistent,
4877                name == null ? ("stop user " + userId) : ("stop " + name));
4878
4879        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4880            if (!doit) {
4881                return true;
4882            }
4883            didSomething = true;
4884        }
4885
4886        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4887            if (!doit) {
4888                return true;
4889            }
4890            didSomething = true;
4891        }
4892
4893        if (name == null) {
4894            // Remove all sticky broadcasts from this user.
4895            mStickyBroadcasts.remove(userId);
4896        }
4897
4898        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4899        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4900                userId, providers)) {
4901            if (!doit) {
4902                return true;
4903            }
4904            didSomething = true;
4905        }
4906        N = providers.size();
4907        for (i=0; i<N; i++) {
4908            removeDyingProviderLocked(null, providers.get(i), true);
4909        }
4910
4911        // Remove transient permissions granted from/to this package/user
4912        removeUriPermissionsForPackageLocked(name, userId, false);
4913
4914        if (name == null || uninstalling) {
4915            // Remove pending intents.  For now we only do this when force
4916            // stopping users, because we have some problems when doing this
4917            // for packages -- app widgets are not currently cleaned up for
4918            // such packages, so they can be left with bad pending intents.
4919            if (mIntentSenderRecords.size() > 0) {
4920                Iterator<WeakReference<PendingIntentRecord>> it
4921                        = mIntentSenderRecords.values().iterator();
4922                while (it.hasNext()) {
4923                    WeakReference<PendingIntentRecord> wpir = it.next();
4924                    if (wpir == null) {
4925                        it.remove();
4926                        continue;
4927                    }
4928                    PendingIntentRecord pir = wpir.get();
4929                    if (pir == null) {
4930                        it.remove();
4931                        continue;
4932                    }
4933                    if (name == null) {
4934                        // Stopping user, remove all objects for the user.
4935                        if (pir.key.userId != userId) {
4936                            // Not the same user, skip it.
4937                            continue;
4938                        }
4939                    } else {
4940                        if (UserHandle.getAppId(pir.uid) != appId) {
4941                            // Different app id, skip it.
4942                            continue;
4943                        }
4944                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4945                            // Different user, skip it.
4946                            continue;
4947                        }
4948                        if (!pir.key.packageName.equals(name)) {
4949                            // Different package, skip it.
4950                            continue;
4951                        }
4952                    }
4953                    if (!doit) {
4954                        return true;
4955                    }
4956                    didSomething = true;
4957                    it.remove();
4958                    pir.canceled = true;
4959                    if (pir.key.activity != null) {
4960                        pir.key.activity.pendingResults.remove(pir.ref);
4961                    }
4962                }
4963            }
4964        }
4965
4966        if (doit) {
4967            if (purgeCache && name != null) {
4968                AttributeCache ac = AttributeCache.instance();
4969                if (ac != null) {
4970                    ac.removePackage(name);
4971                }
4972            }
4973            if (mBooted) {
4974                mStackSupervisor.resumeTopActivitiesLocked();
4975                mStackSupervisor.scheduleIdleLocked();
4976            }
4977        }
4978
4979        return didSomething;
4980    }
4981
4982    private final boolean removeProcessLocked(ProcessRecord app,
4983            boolean callerWillRestart, boolean allowRestart, String reason) {
4984        final String name = app.processName;
4985        final int uid = app.uid;
4986        if (DEBUG_PROCESSES) Slog.d(
4987            TAG, "Force removing proc " + app.toShortString() + " (" + name
4988            + "/" + uid + ")");
4989
4990        mProcessNames.remove(name, uid);
4991        mIsolatedProcesses.remove(app.uid);
4992        if (mHeavyWeightProcess == app) {
4993            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4994                    mHeavyWeightProcess.userId, 0));
4995            mHeavyWeightProcess = null;
4996        }
4997        boolean needRestart = false;
4998        if (app.pid > 0 && app.pid != MY_PID) {
4999            int pid = app.pid;
5000            synchronized (mPidsSelfLocked) {
5001                mPidsSelfLocked.remove(pid);
5002                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5003            }
5004            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5005                    app.processName, app.info.uid);
5006            if (app.isolated) {
5007                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5008            }
5009            killUnneededProcessLocked(app, reason);
5010            handleAppDiedLocked(app, true, allowRestart);
5011            removeLruProcessLocked(app);
5012
5013            if (app.persistent && !app.isolated) {
5014                if (!callerWillRestart) {
5015                    addAppLocked(app.info, false);
5016                } else {
5017                    needRestart = true;
5018                }
5019            }
5020        } else {
5021            mRemovedProcesses.add(app);
5022        }
5023
5024        return needRestart;
5025    }
5026
5027    private final void processStartTimedOutLocked(ProcessRecord app) {
5028        final int pid = app.pid;
5029        boolean gone = false;
5030        synchronized (mPidsSelfLocked) {
5031            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5032            if (knownApp != null && knownApp.thread == null) {
5033                mPidsSelfLocked.remove(pid);
5034                gone = true;
5035            }
5036        }
5037
5038        if (gone) {
5039            Slog.w(TAG, "Process " + app + " failed to attach");
5040            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5041                    pid, app.uid, app.processName);
5042            mProcessNames.remove(app.processName, app.uid);
5043            mIsolatedProcesses.remove(app.uid);
5044            if (mHeavyWeightProcess == app) {
5045                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5046                        mHeavyWeightProcess.userId, 0));
5047                mHeavyWeightProcess = null;
5048            }
5049            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5050                    app.processName, app.info.uid);
5051            if (app.isolated) {
5052                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5053            }
5054            // Take care of any launching providers waiting for this process.
5055            checkAppInLaunchingProvidersLocked(app, true);
5056            // Take care of any services that are waiting for the process.
5057            mServices.processStartTimedOutLocked(app);
5058            killUnneededProcessLocked(app, "start timeout");
5059            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5060                Slog.w(TAG, "Unattached app died before backup, skipping");
5061                try {
5062                    IBackupManager bm = IBackupManager.Stub.asInterface(
5063                            ServiceManager.getService(Context.BACKUP_SERVICE));
5064                    bm.agentDisconnected(app.info.packageName);
5065                } catch (RemoteException e) {
5066                    // Can't happen; the backup manager is local
5067                }
5068            }
5069            if (isPendingBroadcastProcessLocked(pid)) {
5070                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5071                skipPendingBroadcastLocked(pid);
5072            }
5073        } else {
5074            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5075        }
5076    }
5077
5078    private final boolean attachApplicationLocked(IApplicationThread thread,
5079            int pid) {
5080
5081        // Find the application record that is being attached...  either via
5082        // the pid if we are running in multiple processes, or just pull the
5083        // next app record if we are emulating process with anonymous threads.
5084        ProcessRecord app;
5085        if (pid != MY_PID && pid >= 0) {
5086            synchronized (mPidsSelfLocked) {
5087                app = mPidsSelfLocked.get(pid);
5088            }
5089        } else {
5090            app = null;
5091        }
5092
5093        if (app == null) {
5094            Slog.w(TAG, "No pending application record for pid " + pid
5095                    + " (IApplicationThread " + thread + "); dropping process");
5096            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5097            if (pid > 0 && pid != MY_PID) {
5098                Process.killProcessQuiet(pid);
5099            } else {
5100                try {
5101                    thread.scheduleExit();
5102                } catch (Exception e) {
5103                    // Ignore exceptions.
5104                }
5105            }
5106            return false;
5107        }
5108
5109        // If this application record is still attached to a previous
5110        // process, clean it up now.
5111        if (app.thread != null) {
5112            handleAppDiedLocked(app, true, true);
5113        }
5114
5115        // Tell the process all about itself.
5116
5117        if (localLOGV) Slog.v(
5118                TAG, "Binding process pid " + pid + " to record " + app);
5119
5120        final String processName = app.processName;
5121        try {
5122            AppDeathRecipient adr = new AppDeathRecipient(
5123                    app, pid, thread);
5124            thread.asBinder().linkToDeath(adr, 0);
5125            app.deathRecipient = adr;
5126        } catch (RemoteException e) {
5127            app.resetPackageList(mProcessStats);
5128            startProcessLocked(app, "link fail", processName);
5129            return false;
5130        }
5131
5132        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5133
5134        app.makeActive(thread, mProcessStats);
5135        app.curAdj = app.setAdj = -100;
5136        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5137        app.forcingToForeground = null;
5138        updateProcessForegroundLocked(app, false, false);
5139        app.hasShownUi = false;
5140        app.debugging = false;
5141        app.cached = false;
5142
5143        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5144
5145        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5146        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5147
5148        if (!normalMode) {
5149            Slog.i(TAG, "Launching preboot mode app: " + app);
5150        }
5151
5152        if (localLOGV) Slog.v(
5153            TAG, "New app record " + app
5154            + " thread=" + thread.asBinder() + " pid=" + pid);
5155        try {
5156            int testMode = IApplicationThread.DEBUG_OFF;
5157            if (mDebugApp != null && mDebugApp.equals(processName)) {
5158                testMode = mWaitForDebugger
5159                    ? IApplicationThread.DEBUG_WAIT
5160                    : IApplicationThread.DEBUG_ON;
5161                app.debugging = true;
5162                if (mDebugTransient) {
5163                    mDebugApp = mOrigDebugApp;
5164                    mWaitForDebugger = mOrigWaitForDebugger;
5165                }
5166            }
5167            String profileFile = app.instrumentationProfileFile;
5168            ParcelFileDescriptor profileFd = null;
5169            boolean profileAutoStop = false;
5170            if (mProfileApp != null && mProfileApp.equals(processName)) {
5171                mProfileProc = app;
5172                profileFile = mProfileFile;
5173                profileFd = mProfileFd;
5174                profileAutoStop = mAutoStopProfiler;
5175            }
5176            boolean enableOpenGlTrace = false;
5177            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5178                enableOpenGlTrace = true;
5179                mOpenGlTraceApp = null;
5180            }
5181
5182            // If the app is being launched for restore or full backup, set it up specially
5183            boolean isRestrictedBackupMode = false;
5184            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5185                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5186                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5187                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5188            }
5189
5190            ensurePackageDexOpt(app.instrumentationInfo != null
5191                    ? app.instrumentationInfo.packageName
5192                    : app.info.packageName);
5193            if (app.instrumentationClass != null) {
5194                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5195            }
5196            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5197                    + processName + " with config " + mConfiguration);
5198            ApplicationInfo appInfo = app.instrumentationInfo != null
5199                    ? app.instrumentationInfo : app.info;
5200            app.compat = compatibilityInfoForPackageLocked(appInfo);
5201            if (profileFd != null) {
5202                profileFd = profileFd.dup();
5203            }
5204            thread.bindApplication(processName, appInfo, providers,
5205                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5206                    app.instrumentationArguments, app.instrumentationWatcher,
5207                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5208                    isRestrictedBackupMode || !normalMode, app.persistent,
5209                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5210                    mCoreSettingsObserver.getCoreSettingsLocked());
5211            updateLruProcessLocked(app, false, null);
5212            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5213        } catch (Exception e) {
5214            // todo: Yikes!  What should we do?  For now we will try to
5215            // start another process, but that could easily get us in
5216            // an infinite loop of restarting processes...
5217            Slog.w(TAG, "Exception thrown during bind!", e);
5218
5219            app.resetPackageList(mProcessStats);
5220            app.unlinkDeathRecipient();
5221            startProcessLocked(app, "bind fail", processName);
5222            return false;
5223        }
5224
5225        // Remove this record from the list of starting applications.
5226        mPersistentStartingProcesses.remove(app);
5227        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5228                "Attach application locked removing on hold: " + app);
5229        mProcessesOnHold.remove(app);
5230
5231        boolean badApp = false;
5232        boolean didSomething = false;
5233
5234        // See if the top visible activity is waiting to run in this process...
5235        if (normalMode) {
5236            try {
5237                if (mStackSupervisor.attachApplicationLocked(app)) {
5238                    didSomething = true;
5239                }
5240            } catch (Exception e) {
5241                badApp = true;
5242            }
5243        }
5244
5245        // Find any services that should be running in this process...
5246        if (!badApp) {
5247            try {
5248                didSomething |= mServices.attachApplicationLocked(app, processName);
5249            } catch (Exception e) {
5250                badApp = true;
5251            }
5252        }
5253
5254        // Check if a next-broadcast receiver is in this process...
5255        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5256            try {
5257                didSomething |= sendPendingBroadcastsLocked(app);
5258            } catch (Exception e) {
5259                // If the app died trying to launch the receiver we declare it 'bad'
5260                badApp = true;
5261            }
5262        }
5263
5264        // Check whether the next backup agent is in this process...
5265        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5266            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5267            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5268            try {
5269                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5270                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5271                        mBackupTarget.backupMode);
5272            } catch (Exception e) {
5273                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5274                e.printStackTrace();
5275            }
5276        }
5277
5278        if (badApp) {
5279            // todo: Also need to kill application to deal with all
5280            // kinds of exceptions.
5281            handleAppDiedLocked(app, false, true);
5282            return false;
5283        }
5284
5285        if (!didSomething) {
5286            updateOomAdjLocked();
5287        }
5288
5289        return true;
5290    }
5291
5292    @Override
5293    public final void attachApplication(IApplicationThread thread) {
5294        synchronized (this) {
5295            int callingPid = Binder.getCallingPid();
5296            final long origId = Binder.clearCallingIdentity();
5297            attachApplicationLocked(thread, callingPid);
5298            Binder.restoreCallingIdentity(origId);
5299        }
5300    }
5301
5302    @Override
5303    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5304        final long origId = Binder.clearCallingIdentity();
5305        synchronized (this) {
5306            ActivityStack stack = ActivityRecord.getStackLocked(token);
5307            if (stack != null) {
5308                ActivityRecord r =
5309                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5310                if (stopProfiling) {
5311                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5312                        try {
5313                            mProfileFd.close();
5314                        } catch (IOException e) {
5315                        }
5316                        clearProfilerLocked();
5317                    }
5318                }
5319            }
5320        }
5321        Binder.restoreCallingIdentity(origId);
5322    }
5323
5324    void enableScreenAfterBoot() {
5325        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5326                SystemClock.uptimeMillis());
5327        mWindowManager.enableScreenAfterBoot();
5328
5329        synchronized (this) {
5330            updateEventDispatchingLocked();
5331        }
5332    }
5333
5334    @Override
5335    public void showBootMessage(final CharSequence msg, final boolean always) {
5336        enforceNotIsolatedCaller("showBootMessage");
5337        mWindowManager.showBootMessage(msg, always);
5338    }
5339
5340    @Override
5341    public void dismissKeyguardOnNextActivity() {
5342        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5343        final long token = Binder.clearCallingIdentity();
5344        try {
5345            synchronized (this) {
5346                if (DEBUG_LOCKSCREEN) logLockScreen("");
5347                if (mLockScreenShown) {
5348                    mLockScreenShown = false;
5349                    comeOutOfSleepIfNeededLocked();
5350                }
5351                mStackSupervisor.setDismissKeyguard(true);
5352            }
5353        } finally {
5354            Binder.restoreCallingIdentity(token);
5355        }
5356    }
5357
5358    final void finishBooting() {
5359        // Register receivers to handle package update events
5360        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5361
5362        synchronized (this) {
5363            // Ensure that any processes we had put on hold are now started
5364            // up.
5365            final int NP = mProcessesOnHold.size();
5366            if (NP > 0) {
5367                ArrayList<ProcessRecord> procs =
5368                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5369                for (int ip=0; ip<NP; ip++) {
5370                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5371                            + procs.get(ip));
5372                    startProcessLocked(procs.get(ip), "on-hold", null);
5373                }
5374            }
5375
5376            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5377                // Start looking for apps that are abusing wake locks.
5378                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5379                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5380                // Tell anyone interested that we are done booting!
5381                SystemProperties.set("sys.boot_completed", "1");
5382                SystemProperties.set("dev.bootcomplete", "1");
5383                for (int i=0; i<mStartedUsers.size(); i++) {
5384                    UserStartedState uss = mStartedUsers.valueAt(i);
5385                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5386                        uss.mState = UserStartedState.STATE_RUNNING;
5387                        final int userId = mStartedUsers.keyAt(i);
5388                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5389                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5390                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5391                        broadcastIntentLocked(null, null, intent, null,
5392                                new IIntentReceiver.Stub() {
5393                                    @Override
5394                                    public void performReceive(Intent intent, int resultCode,
5395                                            String data, Bundle extras, boolean ordered,
5396                                            boolean sticky, int sendingUser) {
5397                                        synchronized (ActivityManagerService.this) {
5398                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5399                                                    true, false);
5400                                        }
5401                                    }
5402                                },
5403                                0, null, null,
5404                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5405                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5406                                userId);
5407                    }
5408                }
5409                scheduleStartProfilesLocked();
5410            }
5411        }
5412    }
5413
5414    final void ensureBootCompleted() {
5415        boolean booting;
5416        boolean enableScreen;
5417        synchronized (this) {
5418            booting = mBooting;
5419            mBooting = false;
5420            enableScreen = !mBooted;
5421            mBooted = true;
5422        }
5423
5424        if (booting) {
5425            finishBooting();
5426        }
5427
5428        if (enableScreen) {
5429            enableScreenAfterBoot();
5430        }
5431    }
5432
5433    @Override
5434    public final void activityResumed(IBinder token) {
5435        final long origId = Binder.clearCallingIdentity();
5436        synchronized(this) {
5437            ActivityStack stack = ActivityRecord.getStackLocked(token);
5438            if (stack != null) {
5439                ActivityRecord.activityResumedLocked(token);
5440            }
5441        }
5442        Binder.restoreCallingIdentity(origId);
5443    }
5444
5445    @Override
5446    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5447        final long origId = Binder.clearCallingIdentity();
5448        synchronized(this) {
5449            ActivityStack stack = ActivityRecord.getStackLocked(token);
5450            if (stack != null) {
5451                stack.activityPausedLocked(token, false, persistentState);
5452            }
5453        }
5454        Binder.restoreCallingIdentity(origId);
5455    }
5456
5457    @Override
5458    public final void activityStopped(IBinder token, Bundle icicle,
5459            PersistableBundle persistentState, CharSequence description) {
5460        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5461
5462        // Refuse possible leaked file descriptors
5463        if (icicle != null && icicle.hasFileDescriptors()) {
5464            throw new IllegalArgumentException("File descriptors passed in Bundle");
5465        }
5466
5467        final long origId = Binder.clearCallingIdentity();
5468
5469        synchronized (this) {
5470            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5471            if (r != null) {
5472                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5473            }
5474        }
5475
5476        trimApplications();
5477
5478        Binder.restoreCallingIdentity(origId);
5479    }
5480
5481    @Override
5482    public final void activityDestroyed(IBinder token) {
5483        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5484        synchronized (this) {
5485            ActivityStack stack = ActivityRecord.getStackLocked(token);
5486            if (stack != null) {
5487                stack.activityDestroyedLocked(token);
5488            }
5489        }
5490    }
5491
5492    @Override
5493    public String getCallingPackage(IBinder token) {
5494        synchronized (this) {
5495            ActivityRecord r = getCallingRecordLocked(token);
5496            return r != null ? r.info.packageName : null;
5497        }
5498    }
5499
5500    @Override
5501    public ComponentName getCallingActivity(IBinder token) {
5502        synchronized (this) {
5503            ActivityRecord r = getCallingRecordLocked(token);
5504            return r != null ? r.intent.getComponent() : null;
5505        }
5506    }
5507
5508    private ActivityRecord getCallingRecordLocked(IBinder token) {
5509        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5510        if (r == null) {
5511            return null;
5512        }
5513        return r.resultTo;
5514    }
5515
5516    @Override
5517    public ComponentName getActivityClassForToken(IBinder token) {
5518        synchronized(this) {
5519            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5520            if (r == null) {
5521                return null;
5522            }
5523            return r.intent.getComponent();
5524        }
5525    }
5526
5527    @Override
5528    public String getPackageForToken(IBinder token) {
5529        synchronized(this) {
5530            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5531            if (r == null) {
5532                return null;
5533            }
5534            return r.packageName;
5535        }
5536    }
5537
5538    @Override
5539    public IIntentSender getIntentSender(int type,
5540            String packageName, IBinder token, String resultWho,
5541            int requestCode, Intent[] intents, String[] resolvedTypes,
5542            int flags, Bundle options, int userId) {
5543        enforceNotIsolatedCaller("getIntentSender");
5544        // Refuse possible leaked file descriptors
5545        if (intents != null) {
5546            if (intents.length < 1) {
5547                throw new IllegalArgumentException("Intents array length must be >= 1");
5548            }
5549            for (int i=0; i<intents.length; i++) {
5550                Intent intent = intents[i];
5551                if (intent != null) {
5552                    if (intent.hasFileDescriptors()) {
5553                        throw new IllegalArgumentException("File descriptors passed in Intent");
5554                    }
5555                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5556                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5557                        throw new IllegalArgumentException(
5558                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5559                    }
5560                    intents[i] = new Intent(intent);
5561                }
5562            }
5563            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5564                throw new IllegalArgumentException(
5565                        "Intent array length does not match resolvedTypes length");
5566            }
5567        }
5568        if (options != null) {
5569            if (options.hasFileDescriptors()) {
5570                throw new IllegalArgumentException("File descriptors passed in options");
5571            }
5572        }
5573
5574        synchronized(this) {
5575            int callingUid = Binder.getCallingUid();
5576            int origUserId = userId;
5577            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5578                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5579                    "getIntentSender", null);
5580            if (origUserId == UserHandle.USER_CURRENT) {
5581                // We don't want to evaluate this until the pending intent is
5582                // actually executed.  However, we do want to always do the
5583                // security checking for it above.
5584                userId = UserHandle.USER_CURRENT;
5585            }
5586            try {
5587                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5588                    int uid = AppGlobals.getPackageManager()
5589                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5590                    if (!UserHandle.isSameApp(callingUid, uid)) {
5591                        String msg = "Permission Denial: getIntentSender() from pid="
5592                            + Binder.getCallingPid()
5593                            + ", uid=" + Binder.getCallingUid()
5594                            + ", (need uid=" + uid + ")"
5595                            + " is not allowed to send as package " + packageName;
5596                        Slog.w(TAG, msg);
5597                        throw new SecurityException(msg);
5598                    }
5599                }
5600
5601                return getIntentSenderLocked(type, packageName, callingUid, userId,
5602                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5603
5604            } catch (RemoteException e) {
5605                throw new SecurityException(e);
5606            }
5607        }
5608    }
5609
5610    IIntentSender getIntentSenderLocked(int type, String packageName,
5611            int callingUid, int userId, IBinder token, String resultWho,
5612            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5613            Bundle options) {
5614        if (DEBUG_MU)
5615            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5616        ActivityRecord activity = null;
5617        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5618            activity = ActivityRecord.isInStackLocked(token);
5619            if (activity == null) {
5620                return null;
5621            }
5622            if (activity.finishing) {
5623                return null;
5624            }
5625        }
5626
5627        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5628        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5629        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5630        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5631                |PendingIntent.FLAG_UPDATE_CURRENT);
5632
5633        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5634                type, packageName, activity, resultWho,
5635                requestCode, intents, resolvedTypes, flags, options, userId);
5636        WeakReference<PendingIntentRecord> ref;
5637        ref = mIntentSenderRecords.get(key);
5638        PendingIntentRecord rec = ref != null ? ref.get() : null;
5639        if (rec != null) {
5640            if (!cancelCurrent) {
5641                if (updateCurrent) {
5642                    if (rec.key.requestIntent != null) {
5643                        rec.key.requestIntent.replaceExtras(intents != null ?
5644                                intents[intents.length - 1] : null);
5645                    }
5646                    if (intents != null) {
5647                        intents[intents.length-1] = rec.key.requestIntent;
5648                        rec.key.allIntents = intents;
5649                        rec.key.allResolvedTypes = resolvedTypes;
5650                    } else {
5651                        rec.key.allIntents = null;
5652                        rec.key.allResolvedTypes = null;
5653                    }
5654                }
5655                return rec;
5656            }
5657            rec.canceled = true;
5658            mIntentSenderRecords.remove(key);
5659        }
5660        if (noCreate) {
5661            return rec;
5662        }
5663        rec = new PendingIntentRecord(this, key, callingUid);
5664        mIntentSenderRecords.put(key, rec.ref);
5665        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5666            if (activity.pendingResults == null) {
5667                activity.pendingResults
5668                        = new HashSet<WeakReference<PendingIntentRecord>>();
5669            }
5670            activity.pendingResults.add(rec.ref);
5671        }
5672        return rec;
5673    }
5674
5675    @Override
5676    public void cancelIntentSender(IIntentSender sender) {
5677        if (!(sender instanceof PendingIntentRecord)) {
5678            return;
5679        }
5680        synchronized(this) {
5681            PendingIntentRecord rec = (PendingIntentRecord)sender;
5682            try {
5683                int uid = AppGlobals.getPackageManager()
5684                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5685                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5686                    String msg = "Permission Denial: cancelIntentSender() from pid="
5687                        + Binder.getCallingPid()
5688                        + ", uid=" + Binder.getCallingUid()
5689                        + " is not allowed to cancel packges "
5690                        + rec.key.packageName;
5691                    Slog.w(TAG, msg);
5692                    throw new SecurityException(msg);
5693                }
5694            } catch (RemoteException e) {
5695                throw new SecurityException(e);
5696            }
5697            cancelIntentSenderLocked(rec, true);
5698        }
5699    }
5700
5701    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5702        rec.canceled = true;
5703        mIntentSenderRecords.remove(rec.key);
5704        if (cleanActivity && rec.key.activity != null) {
5705            rec.key.activity.pendingResults.remove(rec.ref);
5706        }
5707    }
5708
5709    @Override
5710    public String getPackageForIntentSender(IIntentSender pendingResult) {
5711        if (!(pendingResult instanceof PendingIntentRecord)) {
5712            return null;
5713        }
5714        try {
5715            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5716            return res.key.packageName;
5717        } catch (ClassCastException e) {
5718        }
5719        return null;
5720    }
5721
5722    @Override
5723    public int getUidForIntentSender(IIntentSender sender) {
5724        if (sender instanceof PendingIntentRecord) {
5725            try {
5726                PendingIntentRecord res = (PendingIntentRecord)sender;
5727                return res.uid;
5728            } catch (ClassCastException e) {
5729            }
5730        }
5731        return -1;
5732    }
5733
5734    @Override
5735    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5736        if (!(pendingResult instanceof PendingIntentRecord)) {
5737            return false;
5738        }
5739        try {
5740            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5741            if (res.key.allIntents == null) {
5742                return false;
5743            }
5744            for (int i=0; i<res.key.allIntents.length; i++) {
5745                Intent intent = res.key.allIntents[i];
5746                if (intent.getPackage() != null && intent.getComponent() != null) {
5747                    return false;
5748                }
5749            }
5750            return true;
5751        } catch (ClassCastException e) {
5752        }
5753        return false;
5754    }
5755
5756    @Override
5757    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5758        if (!(pendingResult instanceof PendingIntentRecord)) {
5759            return false;
5760        }
5761        try {
5762            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5763            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5764                return true;
5765            }
5766            return false;
5767        } catch (ClassCastException e) {
5768        }
5769        return false;
5770    }
5771
5772    @Override
5773    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5774        if (!(pendingResult instanceof PendingIntentRecord)) {
5775            return null;
5776        }
5777        try {
5778            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5779            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5780        } catch (ClassCastException e) {
5781        }
5782        return null;
5783    }
5784
5785    @Override
5786    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5787        if (!(pendingResult instanceof PendingIntentRecord)) {
5788            return null;
5789        }
5790        try {
5791            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5792            Intent intent = res.key.requestIntent;
5793            if (intent != null) {
5794                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5795                        || res.lastTagPrefix.equals(prefix))) {
5796                    return res.lastTag;
5797                }
5798                res.lastTagPrefix = prefix;
5799                StringBuilder sb = new StringBuilder(128);
5800                if (prefix != null) {
5801                    sb.append(prefix);
5802                }
5803                if (intent.getAction() != null) {
5804                    sb.append(intent.getAction());
5805                } else if (intent.getComponent() != null) {
5806                    intent.getComponent().appendShortString(sb);
5807                } else {
5808                    sb.append("?");
5809                }
5810                return res.lastTag = sb.toString();
5811            }
5812        } catch (ClassCastException e) {
5813        }
5814        return null;
5815    }
5816
5817    @Override
5818    public void setProcessLimit(int max) {
5819        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5820                "setProcessLimit()");
5821        synchronized (this) {
5822            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5823            mProcessLimitOverride = max;
5824        }
5825        trimApplications();
5826    }
5827
5828    @Override
5829    public int getProcessLimit() {
5830        synchronized (this) {
5831            return mProcessLimitOverride;
5832        }
5833    }
5834
5835    void foregroundTokenDied(ForegroundToken token) {
5836        synchronized (ActivityManagerService.this) {
5837            synchronized (mPidsSelfLocked) {
5838                ForegroundToken cur
5839                    = mForegroundProcesses.get(token.pid);
5840                if (cur != token) {
5841                    return;
5842                }
5843                mForegroundProcesses.remove(token.pid);
5844                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5845                if (pr == null) {
5846                    return;
5847                }
5848                pr.forcingToForeground = null;
5849                updateProcessForegroundLocked(pr, false, false);
5850            }
5851            updateOomAdjLocked();
5852        }
5853    }
5854
5855    @Override
5856    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5857        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5858                "setProcessForeground()");
5859        synchronized(this) {
5860            boolean changed = false;
5861
5862            synchronized (mPidsSelfLocked) {
5863                ProcessRecord pr = mPidsSelfLocked.get(pid);
5864                if (pr == null && isForeground) {
5865                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5866                    return;
5867                }
5868                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5869                if (oldToken != null) {
5870                    oldToken.token.unlinkToDeath(oldToken, 0);
5871                    mForegroundProcesses.remove(pid);
5872                    if (pr != null) {
5873                        pr.forcingToForeground = null;
5874                    }
5875                    changed = true;
5876                }
5877                if (isForeground && token != null) {
5878                    ForegroundToken newToken = new ForegroundToken() {
5879                        @Override
5880                        public void binderDied() {
5881                            foregroundTokenDied(this);
5882                        }
5883                    };
5884                    newToken.pid = pid;
5885                    newToken.token = token;
5886                    try {
5887                        token.linkToDeath(newToken, 0);
5888                        mForegroundProcesses.put(pid, newToken);
5889                        pr.forcingToForeground = token;
5890                        changed = true;
5891                    } catch (RemoteException e) {
5892                        // If the process died while doing this, we will later
5893                        // do the cleanup with the process death link.
5894                    }
5895                }
5896            }
5897
5898            if (changed) {
5899                updateOomAdjLocked();
5900            }
5901        }
5902    }
5903
5904    // =========================================================
5905    // PERMISSIONS
5906    // =========================================================
5907
5908    static class PermissionController extends IPermissionController.Stub {
5909        ActivityManagerService mActivityManagerService;
5910        PermissionController(ActivityManagerService activityManagerService) {
5911            mActivityManagerService = activityManagerService;
5912        }
5913
5914        @Override
5915        public boolean checkPermission(String permission, int pid, int uid) {
5916            return mActivityManagerService.checkPermission(permission, pid,
5917                    uid) == PackageManager.PERMISSION_GRANTED;
5918        }
5919    }
5920
5921    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5922        @Override
5923        public int checkComponentPermission(String permission, int pid, int uid,
5924                int owningUid, boolean exported) {
5925            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5926                    owningUid, exported);
5927        }
5928
5929        @Override
5930        public Object getAMSLock() {
5931            return ActivityManagerService.this;
5932        }
5933    }
5934
5935    /**
5936     * This can be called with or without the global lock held.
5937     */
5938    int checkComponentPermission(String permission, int pid, int uid,
5939            int owningUid, boolean exported) {
5940        // We might be performing an operation on behalf of an indirect binder
5941        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5942        // client identity accordingly before proceeding.
5943        Identity tlsIdentity = sCallerIdentity.get();
5944        if (tlsIdentity != null) {
5945            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5946                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5947            uid = tlsIdentity.uid;
5948            pid = tlsIdentity.pid;
5949        }
5950
5951        if (pid == MY_PID) {
5952            return PackageManager.PERMISSION_GRANTED;
5953        }
5954
5955        return ActivityManager.checkComponentPermission(permission, uid,
5956                owningUid, exported);
5957    }
5958
5959    /**
5960     * As the only public entry point for permissions checking, this method
5961     * can enforce the semantic that requesting a check on a null global
5962     * permission is automatically denied.  (Internally a null permission
5963     * string is used when calling {@link #checkComponentPermission} in cases
5964     * when only uid-based security is needed.)
5965     *
5966     * This can be called with or without the global lock held.
5967     */
5968    @Override
5969    public int checkPermission(String permission, int pid, int uid) {
5970        if (permission == null) {
5971            return PackageManager.PERMISSION_DENIED;
5972        }
5973        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5974    }
5975
5976    /**
5977     * Binder IPC calls go through the public entry point.
5978     * This can be called with or without the global lock held.
5979     */
5980    int checkCallingPermission(String permission) {
5981        return checkPermission(permission,
5982                Binder.getCallingPid(),
5983                UserHandle.getAppId(Binder.getCallingUid()));
5984    }
5985
5986    /**
5987     * This can be called with or without the global lock held.
5988     */
5989    void enforceCallingPermission(String permission, String func) {
5990        if (checkCallingPermission(permission)
5991                == PackageManager.PERMISSION_GRANTED) {
5992            return;
5993        }
5994
5995        String msg = "Permission Denial: " + func + " from pid="
5996                + Binder.getCallingPid()
5997                + ", uid=" + Binder.getCallingUid()
5998                + " requires " + permission;
5999        Slog.w(TAG, msg);
6000        throw new SecurityException(msg);
6001    }
6002
6003    /**
6004     * Determine if UID is holding permissions required to access {@link Uri} in
6005     * the given {@link ProviderInfo}. Final permission checking is always done
6006     * in {@link ContentProvider}.
6007     */
6008    private final boolean checkHoldingPermissionsLocked(
6009            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6010        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6011                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6012        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6013            return false;
6014        }
6015
6016        if (pi.applicationInfo.uid == uid) {
6017            return true;
6018        } else if (!pi.exported) {
6019            return false;
6020        }
6021
6022        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6023        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6024        try {
6025            // check if target holds top-level <provider> permissions
6026            if (!readMet && pi.readPermission != null
6027                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6028                readMet = true;
6029            }
6030            if (!writeMet && pi.writePermission != null
6031                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6032                writeMet = true;
6033            }
6034
6035            // track if unprotected read/write is allowed; any denied
6036            // <path-permission> below removes this ability
6037            boolean allowDefaultRead = pi.readPermission == null;
6038            boolean allowDefaultWrite = pi.writePermission == null;
6039
6040            // check if target holds any <path-permission> that match uri
6041            final PathPermission[] pps = pi.pathPermissions;
6042            if (pps != null) {
6043                final String path = grantUri.uri.getPath();
6044                int i = pps.length;
6045                while (i > 0 && (!readMet || !writeMet)) {
6046                    i--;
6047                    PathPermission pp = pps[i];
6048                    if (pp.match(path)) {
6049                        if (!readMet) {
6050                            final String pprperm = pp.getReadPermission();
6051                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6052                                    + pprperm + " for " + pp.getPath()
6053                                    + ": match=" + pp.match(path)
6054                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6055                            if (pprperm != null) {
6056                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6057                                    readMet = true;
6058                                } else {
6059                                    allowDefaultRead = false;
6060                                }
6061                            }
6062                        }
6063                        if (!writeMet) {
6064                            final String ppwperm = pp.getWritePermission();
6065                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6066                                    + ppwperm + " for " + pp.getPath()
6067                                    + ": match=" + pp.match(path)
6068                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6069                            if (ppwperm != null) {
6070                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6071                                    writeMet = true;
6072                                } else {
6073                                    allowDefaultWrite = false;
6074                                }
6075                            }
6076                        }
6077                    }
6078                }
6079            }
6080
6081            // grant unprotected <provider> read/write, if not blocked by
6082            // <path-permission> above
6083            if (allowDefaultRead) readMet = true;
6084            if (allowDefaultWrite) writeMet = true;
6085
6086        } catch (RemoteException e) {
6087            return false;
6088        }
6089
6090        return readMet && writeMet;
6091    }
6092
6093    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6094        ProviderInfo pi = null;
6095        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6096        if (cpr != null) {
6097            pi = cpr.info;
6098        } else {
6099            try {
6100                pi = AppGlobals.getPackageManager().resolveContentProvider(
6101                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6102            } catch (RemoteException ex) {
6103            }
6104        }
6105        return pi;
6106    }
6107
6108    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6109        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6110        if (targetUris != null) {
6111            return targetUris.get(grantUri);
6112        }
6113        return null;
6114    }
6115
6116    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6117            String targetPkg, int targetUid, GrantUri grantUri) {
6118        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6119        if (targetUris == null) {
6120            targetUris = Maps.newArrayMap();
6121            mGrantedUriPermissions.put(targetUid, targetUris);
6122        }
6123
6124        UriPermission perm = targetUris.get(grantUri);
6125        if (perm == null) {
6126            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6127            targetUris.put(grantUri, perm);
6128        }
6129
6130        return perm;
6131    }
6132
6133    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6134            final int modeFlags) {
6135        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6136        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6137                : UriPermission.STRENGTH_OWNED;
6138
6139        // Root gets to do everything.
6140        if (uid == 0) {
6141            return true;
6142        }
6143
6144        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6145        if (perms == null) return false;
6146
6147        // First look for exact match
6148        final UriPermission exactPerm = perms.get(grantUri);
6149        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6150            return true;
6151        }
6152
6153        // No exact match, look for prefixes
6154        final int N = perms.size();
6155        for (int i = 0; i < N; i++) {
6156            final UriPermission perm = perms.valueAt(i);
6157            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6158                    && perm.getStrength(modeFlags) >= minStrength) {
6159                return true;
6160            }
6161        }
6162
6163        return false;
6164    }
6165
6166    @Override
6167    public int checkUriPermission(Uri uri, int pid, int uid,
6168            final int modeFlags, int userId) {
6169        enforceNotIsolatedCaller("checkUriPermission");
6170
6171        // Another redirected-binder-call permissions check as in
6172        // {@link checkComponentPermission}.
6173        Identity tlsIdentity = sCallerIdentity.get();
6174        if (tlsIdentity != null) {
6175            uid = tlsIdentity.uid;
6176            pid = tlsIdentity.pid;
6177        }
6178
6179        // Our own process gets to do everything.
6180        if (pid == MY_PID) {
6181            return PackageManager.PERMISSION_GRANTED;
6182        }
6183        synchronized (this) {
6184            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6185                    ? PackageManager.PERMISSION_GRANTED
6186                    : PackageManager.PERMISSION_DENIED;
6187        }
6188    }
6189
6190    /**
6191     * Check if the targetPkg can be granted permission to access uri by
6192     * the callingUid using the given modeFlags.  Throws a security exception
6193     * if callingUid is not allowed to do this.  Returns the uid of the target
6194     * if the URI permission grant should be performed; returns -1 if it is not
6195     * needed (for example targetPkg already has permission to access the URI).
6196     * If you already know the uid of the target, you can supply it in
6197     * lastTargetUid else set that to -1.
6198     */
6199    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6200            final int modeFlags, int lastTargetUid) {
6201        if (!Intent.isAccessUriMode(modeFlags)) {
6202            return -1;
6203        }
6204
6205        if (targetPkg != null) {
6206            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6207                    "Checking grant " + targetPkg + " permission to " + grantUri);
6208        }
6209
6210        final IPackageManager pm = AppGlobals.getPackageManager();
6211
6212        // If this is not a content: uri, we can't do anything with it.
6213        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6214            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6215                    "Can't grant URI permission for non-content URI: " + grantUri);
6216            return -1;
6217        }
6218
6219        final String authority = grantUri.uri.getAuthority();
6220        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6221        if (pi == null) {
6222            Slog.w(TAG, "No content provider found for permission check: " +
6223                    grantUri.uri.toSafeString());
6224            return -1;
6225        }
6226
6227        int targetUid = lastTargetUid;
6228        if (targetUid < 0 && targetPkg != null) {
6229            try {
6230                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6231                if (targetUid < 0) {
6232                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6233                            "Can't grant URI permission no uid for: " + targetPkg);
6234                    return -1;
6235                }
6236            } catch (RemoteException ex) {
6237                return -1;
6238            }
6239        }
6240
6241        if (targetUid >= 0) {
6242            // First...  does the target actually need this permission?
6243            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6244                // No need to grant the target this permission.
6245                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6246                        "Target " + targetPkg + " already has full permission to " + grantUri);
6247                return -1;
6248            }
6249        } else {
6250            // First...  there is no target package, so can anyone access it?
6251            boolean allowed = pi.exported;
6252            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6253                if (pi.readPermission != null) {
6254                    allowed = false;
6255                }
6256            }
6257            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6258                if (pi.writePermission != null) {
6259                    allowed = false;
6260                }
6261            }
6262            if (allowed) {
6263                return -1;
6264            }
6265        }
6266
6267        // Second...  is the provider allowing granting of URI permissions?
6268        if (!pi.grantUriPermissions) {
6269            throw new SecurityException("Provider " + pi.packageName
6270                    + "/" + pi.name
6271                    + " does not allow granting of Uri permissions (uri "
6272                    + grantUri + ")");
6273        }
6274        if (pi.uriPermissionPatterns != null) {
6275            final int N = pi.uriPermissionPatterns.length;
6276            boolean allowed = false;
6277            for (int i=0; i<N; i++) {
6278                if (pi.uriPermissionPatterns[i] != null
6279                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6280                    allowed = true;
6281                    break;
6282                }
6283            }
6284            if (!allowed) {
6285                throw new SecurityException("Provider " + pi.packageName
6286                        + "/" + pi.name
6287                        + " does not allow granting of permission to path of Uri "
6288                        + grantUri);
6289            }
6290        }
6291
6292        // Third...  does the caller itself have permission to access
6293        // this uri?
6294        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6295            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6296                // Require they hold a strong enough Uri permission
6297                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6298                    throw new SecurityException("Uid " + callingUid
6299                            + " does not have permission to uri " + grantUri);
6300                }
6301            }
6302        }
6303        return targetUid;
6304    }
6305
6306    @Override
6307    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6308            final int modeFlags, int userId) {
6309        enforceNotIsolatedCaller("checkGrantUriPermission");
6310        synchronized(this) {
6311            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6312                    new GrantUri(userId, uri, false), modeFlags, -1);
6313        }
6314    }
6315
6316    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6317            final int modeFlags, UriPermissionOwner owner) {
6318        if (!Intent.isAccessUriMode(modeFlags)) {
6319            return;
6320        }
6321
6322        // So here we are: the caller has the assumed permission
6323        // to the uri, and the target doesn't.  Let's now give this to
6324        // the target.
6325
6326        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6327                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6328
6329        final String authority = grantUri.uri.getAuthority();
6330        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6331        if (pi == null) {
6332            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6333            return;
6334        }
6335
6336        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6337            grantUri.prefix = true;
6338        }
6339        final UriPermission perm = findOrCreateUriPermissionLocked(
6340                pi.packageName, targetPkg, targetUid, grantUri);
6341        perm.grantModes(modeFlags, owner);
6342    }
6343
6344    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6345            final int modeFlags, UriPermissionOwner owner) {
6346        if (targetPkg == null) {
6347            throw new NullPointerException("targetPkg");
6348        }
6349
6350        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6351                -1);
6352        if (targetUid < 0) {
6353            return;
6354        }
6355
6356        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6357                owner);
6358    }
6359
6360    static class NeededUriGrants extends ArrayList<GrantUri> {
6361        final String targetPkg;
6362        final int targetUid;
6363        final int flags;
6364
6365        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6366            this.targetPkg = targetPkg;
6367            this.targetUid = targetUid;
6368            this.flags = flags;
6369        }
6370    }
6371
6372    /**
6373     * Like checkGrantUriPermissionLocked, but takes an Intent.
6374     */
6375    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6376            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6377        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6378                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6379                + " clip=" + (intent != null ? intent.getClipData() : null)
6380                + " from " + intent + "; flags=0x"
6381                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6382
6383        if (targetPkg == null) {
6384            throw new NullPointerException("targetPkg");
6385        }
6386
6387        if (intent == null) {
6388            return null;
6389        }
6390        Uri data = intent.getData();
6391        ClipData clip = intent.getClipData();
6392        if (data == null && clip == null) {
6393            return null;
6394        }
6395
6396        if (data != null) {
6397            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6398            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6399                    needed != null ? needed.targetUid : -1);
6400            if (targetUid > 0) {
6401                if (needed == null) {
6402                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6403                }
6404                needed.add(grantUri);
6405            }
6406        }
6407        if (clip != null) {
6408            for (int i=0; i<clip.getItemCount(); i++) {
6409                Uri uri = clip.getItemAt(i).getUri();
6410                if (uri != null) {
6411                    int targetUid = -1;
6412                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6413                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6414                            needed != null ? needed.targetUid : -1);
6415                    if (targetUid > 0) {
6416                        if (needed == null) {
6417                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6418                        }
6419                        needed.add(grantUri);
6420                    }
6421                } else {
6422                    Intent clipIntent = clip.getItemAt(i).getIntent();
6423                    if (clipIntent != null) {
6424                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6425                                callingUid, targetPkg, clipIntent, mode, needed);
6426                        if (newNeeded != null) {
6427                            needed = newNeeded;
6428                        }
6429                    }
6430                }
6431            }
6432        }
6433
6434        return needed;
6435    }
6436
6437    /**
6438     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6439     */
6440    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6441            UriPermissionOwner owner) {
6442        if (needed != null) {
6443            for (int i=0; i<needed.size(); i++) {
6444                GrantUri grantUri = needed.get(i);
6445                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6446                        grantUri, needed.flags, owner);
6447            }
6448        }
6449    }
6450
6451    void grantUriPermissionFromIntentLocked(int callingUid,
6452            String targetPkg, Intent intent, UriPermissionOwner owner) {
6453        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6454                intent, intent != null ? intent.getFlags() : 0, null);
6455        if (needed == null) {
6456            return;
6457        }
6458
6459        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6460    }
6461
6462    @Override
6463    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6464            final int modeFlags, int userId) {
6465        enforceNotIsolatedCaller("grantUriPermission");
6466        GrantUri grantUri = new GrantUri(userId, uri, false);
6467        synchronized(this) {
6468            final ProcessRecord r = getRecordForAppLocked(caller);
6469            if (r == null) {
6470                throw new SecurityException("Unable to find app for caller "
6471                        + caller
6472                        + " when granting permission to uri " + grantUri);
6473            }
6474            if (targetPkg == null) {
6475                throw new IllegalArgumentException("null target");
6476            }
6477            if (grantUri == null) {
6478                throw new IllegalArgumentException("null uri");
6479            }
6480
6481            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6482                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6483                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6484                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6485
6486            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6487        }
6488    }
6489
6490    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6491        if (perm.modeFlags == 0) {
6492            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6493                    perm.targetUid);
6494            if (perms != null) {
6495                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6496                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6497
6498                perms.remove(perm.uri);
6499                if (perms.isEmpty()) {
6500                    mGrantedUriPermissions.remove(perm.targetUid);
6501                }
6502            }
6503        }
6504    }
6505
6506    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6507        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6508
6509        final IPackageManager pm = AppGlobals.getPackageManager();
6510        final String authority = grantUri.uri.getAuthority();
6511        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6512        if (pi == null) {
6513            Slog.w(TAG, "No content provider found for permission revoke: "
6514                    + grantUri.toSafeString());
6515            return;
6516        }
6517
6518        // Does the caller have this permission on the URI?
6519        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6520            // Right now, if you are not the original owner of the permission,
6521            // you are not allowed to revoke it.
6522            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6523                throw new SecurityException("Uid " + callingUid
6524                        + " does not have permission to uri " + grantUri);
6525            //}
6526        }
6527
6528        boolean persistChanged = false;
6529
6530        // Go through all of the permissions and remove any that match.
6531        int N = mGrantedUriPermissions.size();
6532        for (int i = 0; i < N; i++) {
6533            final int targetUid = mGrantedUriPermissions.keyAt(i);
6534            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6535
6536            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6537                final UriPermission perm = it.next();
6538                if (perm.uri.sourceUserId == grantUri.sourceUserId
6539                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6540                    if (DEBUG_URI_PERMISSION)
6541                        Slog.v(TAG,
6542                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6543                    persistChanged |= perm.revokeModes(
6544                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6545                    if (perm.modeFlags == 0) {
6546                        it.remove();
6547                    }
6548                }
6549            }
6550
6551            if (perms.isEmpty()) {
6552                mGrantedUriPermissions.remove(targetUid);
6553                N--;
6554                i--;
6555            }
6556        }
6557
6558        if (persistChanged) {
6559            schedulePersistUriGrants();
6560        }
6561    }
6562
6563    @Override
6564    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6565            int userId) {
6566        enforceNotIsolatedCaller("revokeUriPermission");
6567        synchronized(this) {
6568            final ProcessRecord r = getRecordForAppLocked(caller);
6569            if (r == null) {
6570                throw new SecurityException("Unable to find app for caller "
6571                        + caller
6572                        + " when revoking permission to uri " + uri);
6573            }
6574            if (uri == null) {
6575                Slog.w(TAG, "revokeUriPermission: null uri");
6576                return;
6577            }
6578
6579            if (!Intent.isAccessUriMode(modeFlags)) {
6580                return;
6581            }
6582
6583            final IPackageManager pm = AppGlobals.getPackageManager();
6584            final String authority = uri.getAuthority();
6585            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6586            if (pi == null) {
6587                Slog.w(TAG, "No content provider found for permission revoke: "
6588                        + uri.toSafeString());
6589                return;
6590            }
6591
6592            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6593        }
6594    }
6595
6596    /**
6597     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6598     * given package.
6599     *
6600     * @param packageName Package name to match, or {@code null} to apply to all
6601     *            packages.
6602     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6603     *            to all users.
6604     * @param persistable If persistable grants should be removed.
6605     */
6606    private void removeUriPermissionsForPackageLocked(
6607            String packageName, int userHandle, boolean persistable) {
6608        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6609            throw new IllegalArgumentException("Must narrow by either package or user");
6610        }
6611
6612        boolean persistChanged = false;
6613
6614        int N = mGrantedUriPermissions.size();
6615        for (int i = 0; i < N; i++) {
6616            final int targetUid = mGrantedUriPermissions.keyAt(i);
6617            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6618
6619            // Only inspect grants matching user
6620            if (userHandle == UserHandle.USER_ALL
6621                    || userHandle == UserHandle.getUserId(targetUid)) {
6622                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6623                    final UriPermission perm = it.next();
6624
6625                    // Only inspect grants matching package
6626                    if (packageName == null || perm.sourcePkg.equals(packageName)
6627                            || perm.targetPkg.equals(packageName)) {
6628                        persistChanged |= perm.revokeModes(
6629                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6630
6631                        // Only remove when no modes remain; any persisted grants
6632                        // will keep this alive.
6633                        if (perm.modeFlags == 0) {
6634                            it.remove();
6635                        }
6636                    }
6637                }
6638
6639                if (perms.isEmpty()) {
6640                    mGrantedUriPermissions.remove(targetUid);
6641                    N--;
6642                    i--;
6643                }
6644            }
6645        }
6646
6647        if (persistChanged) {
6648            schedulePersistUriGrants();
6649        }
6650    }
6651
6652    @Override
6653    public IBinder newUriPermissionOwner(String name) {
6654        enforceNotIsolatedCaller("newUriPermissionOwner");
6655        synchronized(this) {
6656            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6657            return owner.getExternalTokenLocked();
6658        }
6659    }
6660
6661    @Override
6662    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6663            final int modeFlags, int userId) {
6664        synchronized(this) {
6665            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6666            if (owner == null) {
6667                throw new IllegalArgumentException("Unknown owner: " + token);
6668            }
6669            if (fromUid != Binder.getCallingUid()) {
6670                if (Binder.getCallingUid() != Process.myUid()) {
6671                    // Only system code can grant URI permissions on behalf
6672                    // of other users.
6673                    throw new SecurityException("nice try");
6674                }
6675            }
6676            if (targetPkg == null) {
6677                throw new IllegalArgumentException("null target");
6678            }
6679            if (uri == null) {
6680                throw new IllegalArgumentException("null uri");
6681            }
6682
6683            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6684                    modeFlags, owner);
6685        }
6686    }
6687
6688    @Override
6689    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6690        synchronized(this) {
6691            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6692            if (owner == null) {
6693                throw new IllegalArgumentException("Unknown owner: " + token);
6694            }
6695
6696            if (uri == null) {
6697                owner.removeUriPermissionsLocked(mode);
6698            } else {
6699                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6700            }
6701        }
6702    }
6703
6704    private void schedulePersistUriGrants() {
6705        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6706            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6707                    10 * DateUtils.SECOND_IN_MILLIS);
6708        }
6709    }
6710
6711    private void writeGrantedUriPermissions() {
6712        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6713
6714        // Snapshot permissions so we can persist without lock
6715        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6716        synchronized (this) {
6717            final int size = mGrantedUriPermissions.size();
6718            for (int i = 0; i < size; i++) {
6719                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6720                for (UriPermission perm : perms.values()) {
6721                    if (perm.persistedModeFlags != 0) {
6722                        persist.add(perm.snapshot());
6723                    }
6724                }
6725            }
6726        }
6727
6728        FileOutputStream fos = null;
6729        try {
6730            fos = mGrantFile.startWrite();
6731
6732            XmlSerializer out = new FastXmlSerializer();
6733            out.setOutput(fos, "utf-8");
6734            out.startDocument(null, true);
6735            out.startTag(null, TAG_URI_GRANTS);
6736            for (UriPermission.Snapshot perm : persist) {
6737                out.startTag(null, TAG_URI_GRANT);
6738                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6739                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6740                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6741                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6742                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6743                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6744                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6745                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6746                out.endTag(null, TAG_URI_GRANT);
6747            }
6748            out.endTag(null, TAG_URI_GRANTS);
6749            out.endDocument();
6750
6751            mGrantFile.finishWrite(fos);
6752        } catch (IOException e) {
6753            if (fos != null) {
6754                mGrantFile.failWrite(fos);
6755            }
6756        }
6757    }
6758
6759    private void readGrantedUriPermissionsLocked() {
6760        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6761
6762        final long now = System.currentTimeMillis();
6763
6764        FileInputStream fis = null;
6765        try {
6766            fis = mGrantFile.openRead();
6767            final XmlPullParser in = Xml.newPullParser();
6768            in.setInput(fis, null);
6769
6770            int type;
6771            while ((type = in.next()) != END_DOCUMENT) {
6772                final String tag = in.getName();
6773                if (type == START_TAG) {
6774                    if (TAG_URI_GRANT.equals(tag)) {
6775                        final int sourceUserId;
6776                        final int targetUserId;
6777                        final int userHandle = readIntAttribute(in,
6778                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6779                        if (userHandle != UserHandle.USER_NULL) {
6780                            // For backwards compatibility.
6781                            sourceUserId = userHandle;
6782                            targetUserId = userHandle;
6783                        } else {
6784                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6785                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6786                        }
6787                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6788                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6789                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6790                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6791                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6792                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6793
6794                        // Sanity check that provider still belongs to source package
6795                        final ProviderInfo pi = getProviderInfoLocked(
6796                                uri.getAuthority(), sourceUserId);
6797                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6798                            int targetUid = -1;
6799                            try {
6800                                targetUid = AppGlobals.getPackageManager()
6801                                        .getPackageUid(targetPkg, targetUserId);
6802                            } catch (RemoteException e) {
6803                            }
6804                            if (targetUid != -1) {
6805                                final UriPermission perm = findOrCreateUriPermissionLocked(
6806                                        sourcePkg, targetPkg, targetUid,
6807                                        new GrantUri(sourceUserId, uri, prefix));
6808                                perm.initPersistedModes(modeFlags, createdTime);
6809                            }
6810                        } else {
6811                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6812                                    + " but instead found " + pi);
6813                        }
6814                    }
6815                }
6816            }
6817        } catch (FileNotFoundException e) {
6818            // Missing grants is okay
6819        } catch (IOException e) {
6820            Log.wtf(TAG, "Failed reading Uri grants", e);
6821        } catch (XmlPullParserException e) {
6822            Log.wtf(TAG, "Failed reading Uri grants", e);
6823        } finally {
6824            IoUtils.closeQuietly(fis);
6825        }
6826    }
6827
6828    @Override
6829    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6830        enforceNotIsolatedCaller("takePersistableUriPermission");
6831
6832        Preconditions.checkFlagsArgument(modeFlags,
6833                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6834
6835        synchronized (this) {
6836            final int callingUid = Binder.getCallingUid();
6837            boolean persistChanged = false;
6838            GrantUri grantUri = new GrantUri(userId, uri, false);
6839
6840            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6841                    new GrantUri(userId, uri, false));
6842            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6843                    new GrantUri(userId, uri, true));
6844
6845            final boolean exactValid = (exactPerm != null)
6846                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6847            final boolean prefixValid = (prefixPerm != null)
6848                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6849
6850            if (!(exactValid || prefixValid)) {
6851                throw new SecurityException("No persistable permission grants found for UID "
6852                        + callingUid + " and Uri " + grantUri.toSafeString());
6853            }
6854
6855            if (exactValid) {
6856                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6857            }
6858            if (prefixValid) {
6859                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6860            }
6861
6862            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6863
6864            if (persistChanged) {
6865                schedulePersistUriGrants();
6866            }
6867        }
6868    }
6869
6870    @Override
6871    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6872        enforceNotIsolatedCaller("releasePersistableUriPermission");
6873
6874        Preconditions.checkFlagsArgument(modeFlags,
6875                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6876
6877        synchronized (this) {
6878            final int callingUid = Binder.getCallingUid();
6879            boolean persistChanged = false;
6880
6881            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6882                    new GrantUri(userId, uri, false));
6883            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6884                    new GrantUri(userId, uri, true));
6885            if (exactPerm == null && prefixPerm == null) {
6886                throw new SecurityException("No permission grants found for UID " + callingUid
6887                        + " and Uri " + uri.toSafeString());
6888            }
6889
6890            if (exactPerm != null) {
6891                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6892                removeUriPermissionIfNeededLocked(exactPerm);
6893            }
6894            if (prefixPerm != null) {
6895                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6896                removeUriPermissionIfNeededLocked(prefixPerm);
6897            }
6898
6899            if (persistChanged) {
6900                schedulePersistUriGrants();
6901            }
6902        }
6903    }
6904
6905    /**
6906     * Prune any older {@link UriPermission} for the given UID until outstanding
6907     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6908     *
6909     * @return if any mutations occured that require persisting.
6910     */
6911    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6912        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6913        if (perms == null) return false;
6914        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6915
6916        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6917        for (UriPermission perm : perms.values()) {
6918            if (perm.persistedModeFlags != 0) {
6919                persisted.add(perm);
6920            }
6921        }
6922
6923        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6924        if (trimCount <= 0) return false;
6925
6926        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6927        for (int i = 0; i < trimCount; i++) {
6928            final UriPermission perm = persisted.get(i);
6929
6930            if (DEBUG_URI_PERMISSION) {
6931                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6932            }
6933
6934            perm.releasePersistableModes(~0);
6935            removeUriPermissionIfNeededLocked(perm);
6936        }
6937
6938        return true;
6939    }
6940
6941    @Override
6942    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6943            String packageName, boolean incoming) {
6944        enforceNotIsolatedCaller("getPersistedUriPermissions");
6945        Preconditions.checkNotNull(packageName, "packageName");
6946
6947        final int callingUid = Binder.getCallingUid();
6948        final IPackageManager pm = AppGlobals.getPackageManager();
6949        try {
6950            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6951            if (packageUid != callingUid) {
6952                throw new SecurityException(
6953                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6954            }
6955        } catch (RemoteException e) {
6956            throw new SecurityException("Failed to verify package name ownership");
6957        }
6958
6959        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6960        synchronized (this) {
6961            if (incoming) {
6962                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6963                        callingUid);
6964                if (perms == null) {
6965                    Slog.w(TAG, "No permission grants found for " + packageName);
6966                } else {
6967                    for (UriPermission perm : perms.values()) {
6968                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6969                            result.add(perm.buildPersistedPublicApiObject());
6970                        }
6971                    }
6972                }
6973            } else {
6974                final int size = mGrantedUriPermissions.size();
6975                for (int i = 0; i < size; i++) {
6976                    final ArrayMap<GrantUri, UriPermission> perms =
6977                            mGrantedUriPermissions.valueAt(i);
6978                    for (UriPermission perm : perms.values()) {
6979                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6980                            result.add(perm.buildPersistedPublicApiObject());
6981                        }
6982                    }
6983                }
6984            }
6985        }
6986        return new ParceledListSlice<android.content.UriPermission>(result);
6987    }
6988
6989    @Override
6990    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6991        synchronized (this) {
6992            ProcessRecord app =
6993                who != null ? getRecordForAppLocked(who) : null;
6994            if (app == null) return;
6995
6996            Message msg = Message.obtain();
6997            msg.what = WAIT_FOR_DEBUGGER_MSG;
6998            msg.obj = app;
6999            msg.arg1 = waiting ? 1 : 0;
7000            mHandler.sendMessage(msg);
7001        }
7002    }
7003
7004    @Override
7005    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7006        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7007        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7008        outInfo.availMem = Process.getFreeMemory();
7009        outInfo.totalMem = Process.getTotalMemory();
7010        outInfo.threshold = homeAppMem;
7011        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7012        outInfo.hiddenAppThreshold = cachedAppMem;
7013        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7014                ProcessList.SERVICE_ADJ);
7015        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7016                ProcessList.VISIBLE_APP_ADJ);
7017        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7018                ProcessList.FOREGROUND_APP_ADJ);
7019    }
7020
7021    // =========================================================
7022    // TASK MANAGEMENT
7023    // =========================================================
7024
7025    @Override
7026    public List<IAppTask> getAppTasks() {
7027        int callingUid = Binder.getCallingUid();
7028        long ident = Binder.clearCallingIdentity();
7029        synchronized(this) {
7030            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7031            try {
7032                if (localLOGV) Slog.v(TAG, "getAppTasks");
7033
7034                final int N = mRecentTasks.size();
7035                for (int i = 0; i < N; i++) {
7036                    TaskRecord tr = mRecentTasks.get(i);
7037                    // Skip tasks that are not created by the caller
7038                    if (tr.creatorUid == callingUid) {
7039                        ActivityManager.RecentTaskInfo taskInfo =
7040                                createRecentTaskInfoFromTaskRecord(tr);
7041                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7042                        list.add(taskImpl);
7043                    }
7044                }
7045            } finally {
7046                Binder.restoreCallingIdentity(ident);
7047            }
7048            return list;
7049        }
7050    }
7051
7052    @Override
7053    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7054        final int callingUid = Binder.getCallingUid();
7055        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7056
7057        synchronized(this) {
7058            if (localLOGV) Slog.v(
7059                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7060
7061            final boolean allowed = checkCallingPermission(
7062                    android.Manifest.permission.GET_TASKS)
7063                    == PackageManager.PERMISSION_GRANTED;
7064            if (!allowed) {
7065                Slog.w(TAG, "getTasks: caller " + callingUid
7066                        + " does not hold GET_TASKS; limiting output");
7067            }
7068
7069            // TODO: Improve with MRU list from all ActivityStacks.
7070            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7071        }
7072
7073        return list;
7074    }
7075
7076    TaskRecord getMostRecentTask() {
7077        return mRecentTasks.get(0);
7078    }
7079
7080    /**
7081     * Creates a new RecentTaskInfo from a TaskRecord.
7082     */
7083    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7084        ActivityManager.RecentTaskInfo rti
7085                = new ActivityManager.RecentTaskInfo();
7086        rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7087        rti.persistentId = tr.taskId;
7088        rti.baseIntent = new Intent(tr.getBaseIntent());
7089        rti.origActivity = tr.origActivity;
7090        rti.description = tr.lastDescription;
7091        rti.stackId = tr.stack.mStackId;
7092        rti.userId = tr.userId;
7093
7094        // Traverse upwards looking for any break between main task activities and
7095        // utility activities.
7096        final ArrayList<ActivityRecord> activities = tr.mActivities;
7097        int activityNdx;
7098        final int numActivities = activities.size();
7099        for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7100             ++activityNdx) {
7101            final ActivityRecord r = activities.get(activityNdx);
7102            if (r.intent != null &&
7103                    (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7104                            != 0) {
7105                break;
7106            }
7107        }
7108        if (activityNdx > 0) {
7109            // Traverse downwards starting below break looking for set label, icon.
7110            // Note that if there are activities in the task but none of them set the
7111            // recent activity values, then we do not fall back to the last set
7112            // values in the TaskRecord.
7113            rti.activityValues = new ActivityManager.RecentsActivityValues();
7114            for (--activityNdx; activityNdx >= 0; --activityNdx) {
7115                final ActivityRecord r = activities.get(activityNdx);
7116                if (r.activityValues != null) {
7117                    if (rti.activityValues.label == null) {
7118                        rti.activityValues.label = r.activityValues.label;
7119                        tr.lastActivityValues.label = r.activityValues.label;
7120                    }
7121                    if (rti.activityValues.icon == null) {
7122                        rti.activityValues.icon = r.activityValues.icon;
7123                        tr.lastActivityValues.icon = r.activityValues.icon;
7124                    }
7125                    if (rti.activityValues.colorPrimary == 0) {
7126                        rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
7127                        tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
7128                    }
7129                }
7130            }
7131        } else {
7132            // If there are no activity records in this task, then we use the last
7133            // resolved values
7134            rti.activityValues =
7135                    new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
7136        }
7137        return rti;
7138    }
7139
7140    @Override
7141    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7142            int flags, int userId) {
7143        final int callingUid = Binder.getCallingUid();
7144        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7145                false, true, "getRecentTasks", null);
7146
7147        synchronized (this) {
7148            final boolean allowed = checkCallingPermission(
7149                    android.Manifest.permission.GET_TASKS)
7150                    == PackageManager.PERMISSION_GRANTED;
7151            if (!allowed) {
7152                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7153                        + " does not hold GET_TASKS; limiting output");
7154            }
7155            final boolean detailed = checkCallingPermission(
7156                    android.Manifest.permission.GET_DETAILED_TASKS)
7157                    == PackageManager.PERMISSION_GRANTED;
7158
7159            IPackageManager pm = AppGlobals.getPackageManager();
7160
7161            final int N = mRecentTasks.size();
7162            ArrayList<ActivityManager.RecentTaskInfo> res
7163                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7164                            maxNum < N ? maxNum : N);
7165
7166            final Set<Integer> includedUsers;
7167            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7168                includedUsers = getProfileIdsLocked(userId);
7169            } else {
7170                includedUsers = new HashSet<Integer>();
7171            }
7172            includedUsers.add(Integer.valueOf(userId));
7173            for (int i=0; i<N && maxNum > 0; i++) {
7174                TaskRecord tr = mRecentTasks.get(i);
7175                // Only add calling user or related users recent tasks
7176                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7177
7178                // Return the entry if desired by the caller.  We always return
7179                // the first entry, because callers always expect this to be the
7180                // foreground app.  We may filter others if the caller has
7181                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7182                // we should exclude the entry.
7183
7184                if (i == 0
7185                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7186                        || (tr.intent == null)
7187                        || ((tr.intent.getFlags()
7188                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7189                    if (!allowed) {
7190                        // If the caller doesn't have the GET_TASKS permission, then only
7191                        // allow them to see a small subset of tasks -- their own and home.
7192                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7193                            continue;
7194                        }
7195                    }
7196
7197                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7198                    if (!detailed) {
7199                        rti.baseIntent.replaceExtras((Bundle)null);
7200                    }
7201
7202                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7203                        // Check whether this activity is currently available.
7204                        try {
7205                            if (rti.origActivity != null) {
7206                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7207                                        == null) {
7208                                    continue;
7209                                }
7210                            } else if (rti.baseIntent != null) {
7211                                if (pm.queryIntentActivities(rti.baseIntent,
7212                                        null, 0, userId) == null) {
7213                                    continue;
7214                                }
7215                            }
7216                        } catch (RemoteException e) {
7217                            // Will never happen.
7218                        }
7219                    }
7220
7221                    res.add(rti);
7222                    maxNum--;
7223                }
7224            }
7225            return res;
7226        }
7227    }
7228
7229    private TaskRecord recentTaskForIdLocked(int id) {
7230        final int N = mRecentTasks.size();
7231            for (int i=0; i<N; i++) {
7232                TaskRecord tr = mRecentTasks.get(i);
7233                if (tr.taskId == id) {
7234                    return tr;
7235                }
7236            }
7237            return null;
7238    }
7239
7240    @Override
7241    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7242        synchronized (this) {
7243            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7244                    "getTaskThumbnails()");
7245            TaskRecord tr = recentTaskForIdLocked(id);
7246            if (tr != null) {
7247                return tr.getTaskThumbnailsLocked();
7248            }
7249        }
7250        return null;
7251    }
7252
7253    @Override
7254    public Bitmap getTaskTopThumbnail(int id) {
7255        synchronized (this) {
7256            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7257                    "getTaskTopThumbnail()");
7258            TaskRecord tr = recentTaskForIdLocked(id);
7259            if (tr != null) {
7260                return tr.getTaskTopThumbnailLocked();
7261            }
7262        }
7263        return null;
7264    }
7265
7266    @Override
7267    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
7268        synchronized (this) {
7269            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7270            if (r != null) {
7271                r.activityValues = rav;
7272            }
7273        }
7274    }
7275
7276    @Override
7277    public boolean removeSubTask(int taskId, int subTaskIndex) {
7278        synchronized (this) {
7279            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7280                    "removeSubTask()");
7281            long ident = Binder.clearCallingIdentity();
7282            try {
7283                TaskRecord tr = recentTaskForIdLocked(taskId);
7284                if (tr != null) {
7285                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7286                }
7287                return false;
7288            } finally {
7289                Binder.restoreCallingIdentity(ident);
7290            }
7291        }
7292    }
7293
7294    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7295        if (!pr.killedByAm) {
7296            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7297            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7298                    pr.processName, pr.setAdj, reason);
7299            pr.killedByAm = true;
7300            Process.killProcessQuiet(pr.pid);
7301        }
7302    }
7303
7304    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7305        tr.disposeThumbnail();
7306        mRecentTasks.remove(tr);
7307        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7308        Intent baseIntent = new Intent(
7309                tr.intent != null ? tr.intent : tr.affinityIntent);
7310        ComponentName component = baseIntent.getComponent();
7311        if (component == null) {
7312            Slog.w(TAG, "Now component for base intent of task: " + tr);
7313            return;
7314        }
7315
7316        // Find any running services associated with this app.
7317        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7318
7319        if (killProcesses) {
7320            // Find any running processes associated with this app.
7321            final String pkg = component.getPackageName();
7322            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7323            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7324            for (int i=0; i<pmap.size(); i++) {
7325                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7326                for (int j=0; j<uids.size(); j++) {
7327                    ProcessRecord proc = uids.valueAt(j);
7328                    if (proc.userId != tr.userId) {
7329                        continue;
7330                    }
7331                    if (!proc.pkgList.containsKey(pkg)) {
7332                        continue;
7333                    }
7334                    procs.add(proc);
7335                }
7336            }
7337
7338            // Kill the running processes.
7339            for (int i=0; i<procs.size(); i++) {
7340                ProcessRecord pr = procs.get(i);
7341                if (pr == mHomeProcess) {
7342                    // Don't kill the home process along with tasks from the same package.
7343                    continue;
7344                }
7345                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7346                    killUnneededProcessLocked(pr, "remove task");
7347                } else {
7348                    pr.waitingToKill = "remove task";
7349                }
7350            }
7351        }
7352    }
7353
7354    /**
7355     * Removes the task with the specified task id.
7356     *
7357     * @param taskId Identifier of the task to be removed.
7358     * @param flags Additional operational flags.  May be 0 or
7359     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7360     * @return Returns true if the given task was found and removed.
7361     */
7362    private boolean removeTaskByIdLocked(int taskId, int flags) {
7363        TaskRecord tr = recentTaskForIdLocked(taskId);
7364        if (tr != null) {
7365            tr.removeTaskActivitiesLocked(-1, false);
7366            cleanUpRemovedTaskLocked(tr, flags);
7367            return true;
7368        }
7369        return false;
7370    }
7371
7372    @Override
7373    public boolean removeTask(int taskId, int flags) {
7374        synchronized (this) {
7375            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7376                    "removeTask()");
7377            long ident = Binder.clearCallingIdentity();
7378            try {
7379                return removeTaskByIdLocked(taskId, flags);
7380            } finally {
7381                Binder.restoreCallingIdentity(ident);
7382            }
7383        }
7384    }
7385
7386    /**
7387     * TODO: Add mController hook
7388     */
7389    @Override
7390    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7391        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7392                "moveTaskToFront()");
7393
7394        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7395        synchronized(this) {
7396            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7397                    Binder.getCallingUid(), "Task to front")) {
7398                ActivityOptions.abort(options);
7399                return;
7400            }
7401            final long origId = Binder.clearCallingIdentity();
7402            try {
7403                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7404                if (task == null) {
7405                    return;
7406                }
7407                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7408                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7409                    return;
7410                }
7411                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7412            } finally {
7413                Binder.restoreCallingIdentity(origId);
7414            }
7415            ActivityOptions.abort(options);
7416        }
7417    }
7418
7419    @Override
7420    public void moveTaskToBack(int taskId) {
7421        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7422                "moveTaskToBack()");
7423
7424        synchronized(this) {
7425            TaskRecord tr = recentTaskForIdLocked(taskId);
7426            if (tr != null) {
7427                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7428                ActivityStack stack = tr.stack;
7429                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7430                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7431                            Binder.getCallingUid(), "Task to back")) {
7432                        return;
7433                    }
7434                }
7435                final long origId = Binder.clearCallingIdentity();
7436                try {
7437                    stack.moveTaskToBackLocked(taskId, null);
7438                } finally {
7439                    Binder.restoreCallingIdentity(origId);
7440                }
7441            }
7442        }
7443    }
7444
7445    /**
7446     * Moves an activity, and all of the other activities within the same task, to the bottom
7447     * of the history stack.  The activity's order within the task is unchanged.
7448     *
7449     * @param token A reference to the activity we wish to move
7450     * @param nonRoot If false then this only works if the activity is the root
7451     *                of a task; if true it will work for any activity in a task.
7452     * @return Returns true if the move completed, false if not.
7453     */
7454    @Override
7455    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7456        enforceNotIsolatedCaller("moveActivityTaskToBack");
7457        synchronized(this) {
7458            final long origId = Binder.clearCallingIdentity();
7459            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7460            if (taskId >= 0) {
7461                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7462            }
7463            Binder.restoreCallingIdentity(origId);
7464        }
7465        return false;
7466    }
7467
7468    @Override
7469    public void moveTaskBackwards(int task) {
7470        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7471                "moveTaskBackwards()");
7472
7473        synchronized(this) {
7474            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7475                    Binder.getCallingUid(), "Task backwards")) {
7476                return;
7477            }
7478            final long origId = Binder.clearCallingIdentity();
7479            moveTaskBackwardsLocked(task);
7480            Binder.restoreCallingIdentity(origId);
7481        }
7482    }
7483
7484    private final void moveTaskBackwardsLocked(int task) {
7485        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7486    }
7487
7488    @Override
7489    public IBinder getHomeActivityToken() throws RemoteException {
7490        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7491                "getHomeActivityToken()");
7492        synchronized (this) {
7493            return mStackSupervisor.getHomeActivityToken();
7494        }
7495    }
7496
7497    @Override
7498    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7499            IActivityContainerCallback callback) throws RemoteException {
7500        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7501                "createActivityContainer()");
7502        synchronized (this) {
7503            if (parentActivityToken == null) {
7504                throw new IllegalArgumentException("parent token must not be null");
7505            }
7506            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7507            if (r == null) {
7508                return null;
7509            }
7510            if (callback == null) {
7511                throw new IllegalArgumentException("callback must not be null");
7512            }
7513            return mStackSupervisor.createActivityContainer(r, callback);
7514        }
7515    }
7516
7517    @Override
7518    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7519        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7520                "deleteActivityContainer()");
7521        synchronized (this) {
7522            mStackSupervisor.deleteActivityContainer(container);
7523        }
7524    }
7525
7526    @Override
7527    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7528            throws RemoteException {
7529        synchronized (this) {
7530            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7531            if (stack != null) {
7532                return stack.mActivityContainer;
7533            }
7534            return null;
7535        }
7536    }
7537
7538    @Override
7539    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7540        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7541                "moveTaskToStack()");
7542        if (stackId == HOME_STACK_ID) {
7543            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7544                    new RuntimeException("here").fillInStackTrace());
7545        }
7546        synchronized (this) {
7547            long ident = Binder.clearCallingIdentity();
7548            try {
7549                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7550                        + stackId + " toTop=" + toTop);
7551                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7552            } finally {
7553                Binder.restoreCallingIdentity(ident);
7554            }
7555        }
7556    }
7557
7558    @Override
7559    public void resizeStack(int stackBoxId, Rect bounds) {
7560        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7561                "resizeStackBox()");
7562        long ident = Binder.clearCallingIdentity();
7563        try {
7564            mWindowManager.resizeStack(stackBoxId, bounds);
7565        } finally {
7566            Binder.restoreCallingIdentity(ident);
7567        }
7568    }
7569
7570    @Override
7571    public List<StackInfo> getAllStackInfos() {
7572        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7573                "getAllStackInfos()");
7574        long ident = Binder.clearCallingIdentity();
7575        try {
7576            synchronized (this) {
7577                return mStackSupervisor.getAllStackInfosLocked();
7578            }
7579        } finally {
7580            Binder.restoreCallingIdentity(ident);
7581        }
7582    }
7583
7584    @Override
7585    public StackInfo getStackInfo(int stackId) {
7586        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7587                "getStackInfo()");
7588        long ident = Binder.clearCallingIdentity();
7589        try {
7590            synchronized (this) {
7591                return mStackSupervisor.getStackInfoLocked(stackId);
7592            }
7593        } finally {
7594            Binder.restoreCallingIdentity(ident);
7595        }
7596    }
7597
7598    @Override
7599    public boolean isInHomeStack(int taskId) {
7600        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7601                "getStackInfo()");
7602        long ident = Binder.clearCallingIdentity();
7603        try {
7604            synchronized (this) {
7605                TaskRecord tr = recentTaskForIdLocked(taskId);
7606                if (tr != null) {
7607                    return tr.stack.isHomeStack();
7608                }
7609            }
7610        } finally {
7611            Binder.restoreCallingIdentity(ident);
7612        }
7613        return false;
7614    }
7615
7616    @Override
7617    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7618        synchronized(this) {
7619            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7620        }
7621    }
7622
7623    private boolean isLockTaskAuthorized(ComponentName name) {
7624//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7625//                "startLockTaskMode()");
7626//        DevicePolicyManager dpm = (DevicePolicyManager)
7627//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7628//        return dpm != null && dpm.isLockTaskPermitted(name);
7629        return true;
7630    }
7631
7632    private void startLockTaskMode(TaskRecord task) {
7633        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7634            return;
7635        }
7636        long ident = Binder.clearCallingIdentity();
7637        try {
7638            synchronized (this) {
7639                // Since we lost lock on task, make sure it is still there.
7640                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7641                if (task != null) {
7642                    mStackSupervisor.setLockTaskModeLocked(task);
7643                }
7644            }
7645        } finally {
7646            Binder.restoreCallingIdentity(ident);
7647        }
7648    }
7649
7650    @Override
7651    public void startLockTaskMode(int taskId) {
7652        long ident = Binder.clearCallingIdentity();
7653        try {
7654            final TaskRecord task;
7655            synchronized (this) {
7656                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7657            }
7658            if (task != null) {
7659                startLockTaskMode(task);
7660            }
7661        } finally {
7662            Binder.restoreCallingIdentity(ident);
7663        }
7664    }
7665
7666    @Override
7667    public void startLockTaskMode(IBinder token) {
7668        long ident = Binder.clearCallingIdentity();
7669        try {
7670            final TaskRecord task;
7671            synchronized (this) {
7672                final ActivityRecord r = ActivityRecord.forToken(token);
7673                if (r == null) {
7674                    return;
7675                }
7676                task = r.task;
7677            }
7678            if (task != null) {
7679                startLockTaskMode(task);
7680            }
7681        } finally {
7682            Binder.restoreCallingIdentity(ident);
7683        }
7684    }
7685
7686    @Override
7687    public void stopLockTaskMode() {
7688//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7689//                "stopLockTaskMode()");
7690        synchronized (this) {
7691            mStackSupervisor.setLockTaskModeLocked(null);
7692        }
7693    }
7694
7695    @Override
7696    public boolean isInLockTaskMode() {
7697        synchronized (this) {
7698            return mStackSupervisor.isInLockTaskMode();
7699        }
7700    }
7701
7702    // =========================================================
7703    // CONTENT PROVIDERS
7704    // =========================================================
7705
7706    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7707        List<ProviderInfo> providers = null;
7708        try {
7709            providers = AppGlobals.getPackageManager().
7710                queryContentProviders(app.processName, app.uid,
7711                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7712        } catch (RemoteException ex) {
7713        }
7714        if (DEBUG_MU)
7715            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7716        int userId = app.userId;
7717        if (providers != null) {
7718            int N = providers.size();
7719            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7720            for (int i=0; i<N; i++) {
7721                ProviderInfo cpi =
7722                    (ProviderInfo)providers.get(i);
7723                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7724                        cpi.name, cpi.flags);
7725                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7726                    // This is a singleton provider, but a user besides the
7727                    // default user is asking to initialize a process it runs
7728                    // in...  well, no, it doesn't actually run in this process,
7729                    // it runs in the process of the default user.  Get rid of it.
7730                    providers.remove(i);
7731                    N--;
7732                    i--;
7733                    continue;
7734                }
7735
7736                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7737                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7738                if (cpr == null) {
7739                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7740                    mProviderMap.putProviderByClass(comp, cpr);
7741                }
7742                if (DEBUG_MU)
7743                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7744                app.pubProviders.put(cpi.name, cpr);
7745                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7746                    // Don't add this if it is a platform component that is marked
7747                    // to run in multiple processes, because this is actually
7748                    // part of the framework so doesn't make sense to track as a
7749                    // separate apk in the process.
7750                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7751                }
7752                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7753            }
7754        }
7755        return providers;
7756    }
7757
7758    /**
7759     * Check if {@link ProcessRecord} has a possible chance at accessing the
7760     * given {@link ProviderInfo}. Final permission checking is always done
7761     * in {@link ContentProvider}.
7762     */
7763    private final String checkContentProviderPermissionLocked(
7764            ProviderInfo cpi, ProcessRecord r, int userId) {
7765        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7766        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7767        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7768        // Looking for cross-user grants before to enforce the typical cross-users permissions
7769        if (userId != UserHandle.getUserId(callingUid)) {
7770            if (perms != null) {
7771                for (GrantUri grantUri : perms.keySet()) {
7772                    if (grantUri.sourceUserId == userId) {
7773                        String authority = grantUri.uri.getAuthority();
7774                        if (authority.equals(cpi.authority)) {
7775                            return null;
7776                        }
7777                    }
7778                }
7779            }
7780        }
7781        userId = handleIncomingUser(callingPid, callingUid, userId,
7782                false, true, "checkContentProviderPermissionLocked", null);
7783        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7784                cpi.applicationInfo.uid, cpi.exported)
7785                == PackageManager.PERMISSION_GRANTED) {
7786            return null;
7787        }
7788        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7789                cpi.applicationInfo.uid, cpi.exported)
7790                == PackageManager.PERMISSION_GRANTED) {
7791            return null;
7792        }
7793
7794        PathPermission[] pps = cpi.pathPermissions;
7795        if (pps != null) {
7796            int i = pps.length;
7797            while (i > 0) {
7798                i--;
7799                PathPermission pp = pps[i];
7800                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7801                        cpi.applicationInfo.uid, cpi.exported)
7802                        == PackageManager.PERMISSION_GRANTED) {
7803                    return null;
7804                }
7805                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7806                        cpi.applicationInfo.uid, cpi.exported)
7807                        == PackageManager.PERMISSION_GRANTED) {
7808                    return null;
7809                }
7810            }
7811        }
7812
7813        if (perms != null) {
7814            for (GrantUri grantUri : perms.keySet()) {
7815                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7816                    return null;
7817                }
7818            }
7819        }
7820
7821        String msg;
7822        if (!cpi.exported) {
7823            msg = "Permission Denial: opening provider " + cpi.name
7824                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7825                    + ", uid=" + callingUid + ") that is not exported from uid "
7826                    + cpi.applicationInfo.uid;
7827        } else {
7828            msg = "Permission Denial: opening provider " + cpi.name
7829                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7830                    + ", uid=" + callingUid + ") requires "
7831                    + cpi.readPermission + " or " + cpi.writePermission;
7832        }
7833        Slog.w(TAG, msg);
7834        return msg;
7835    }
7836
7837    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7838            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7839        if (r != null) {
7840            for (int i=0; i<r.conProviders.size(); i++) {
7841                ContentProviderConnection conn = r.conProviders.get(i);
7842                if (conn.provider == cpr) {
7843                    if (DEBUG_PROVIDER) Slog.v(TAG,
7844                            "Adding provider requested by "
7845                            + r.processName + " from process "
7846                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7847                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7848                    if (stable) {
7849                        conn.stableCount++;
7850                        conn.numStableIncs++;
7851                    } else {
7852                        conn.unstableCount++;
7853                        conn.numUnstableIncs++;
7854                    }
7855                    return conn;
7856                }
7857            }
7858            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7859            if (stable) {
7860                conn.stableCount = 1;
7861                conn.numStableIncs = 1;
7862            } else {
7863                conn.unstableCount = 1;
7864                conn.numUnstableIncs = 1;
7865            }
7866            cpr.connections.add(conn);
7867            r.conProviders.add(conn);
7868            return conn;
7869        }
7870        cpr.addExternalProcessHandleLocked(externalProcessToken);
7871        return null;
7872    }
7873
7874    boolean decProviderCountLocked(ContentProviderConnection conn,
7875            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7876        if (conn != null) {
7877            cpr = conn.provider;
7878            if (DEBUG_PROVIDER) Slog.v(TAG,
7879                    "Removing provider requested by "
7880                    + conn.client.processName + " from process "
7881                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7882                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7883            if (stable) {
7884                conn.stableCount--;
7885            } else {
7886                conn.unstableCount--;
7887            }
7888            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7889                cpr.connections.remove(conn);
7890                conn.client.conProviders.remove(conn);
7891                return true;
7892            }
7893            return false;
7894        }
7895        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7896        return false;
7897    }
7898
7899    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7900            String name, IBinder token, boolean stable, int userId) {
7901        ContentProviderRecord cpr;
7902        ContentProviderConnection conn = null;
7903        ProviderInfo cpi = null;
7904
7905        synchronized(this) {
7906            ProcessRecord r = null;
7907            if (caller != null) {
7908                r = getRecordForAppLocked(caller);
7909                if (r == null) {
7910                    throw new SecurityException(
7911                            "Unable to find app for caller " + caller
7912                          + " (pid=" + Binder.getCallingPid()
7913                          + ") when getting content provider " + name);
7914                }
7915            }
7916
7917            // First check if this content provider has been published...
7918            cpr = mProviderMap.getProviderByName(name, userId);
7919            boolean providerRunning = cpr != null;
7920            if (providerRunning) {
7921                cpi = cpr.info;
7922                String msg;
7923                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7924                    throw new SecurityException(msg);
7925                }
7926
7927                if (r != null && cpr.canRunHere(r)) {
7928                    // This provider has been published or is in the process
7929                    // of being published...  but it is also allowed to run
7930                    // in the caller's process, so don't make a connection
7931                    // and just let the caller instantiate its own instance.
7932                    ContentProviderHolder holder = cpr.newHolder(null);
7933                    // don't give caller the provider object, it needs
7934                    // to make its own.
7935                    holder.provider = null;
7936                    return holder;
7937                }
7938
7939                final long origId = Binder.clearCallingIdentity();
7940
7941                // In this case the provider instance already exists, so we can
7942                // return it right away.
7943                conn = incProviderCountLocked(r, cpr, token, stable);
7944                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7945                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7946                        // If this is a perceptible app accessing the provider,
7947                        // make sure to count it as being accessed and thus
7948                        // back up on the LRU list.  This is good because
7949                        // content providers are often expensive to start.
7950                        updateLruProcessLocked(cpr.proc, false, null);
7951                    }
7952                }
7953
7954                if (cpr.proc != null) {
7955                    if (false) {
7956                        if (cpr.name.flattenToShortString().equals(
7957                                "com.android.providers.calendar/.CalendarProvider2")) {
7958                            Slog.v(TAG, "****************** KILLING "
7959                                + cpr.name.flattenToShortString());
7960                            Process.killProcess(cpr.proc.pid);
7961                        }
7962                    }
7963                    boolean success = updateOomAdjLocked(cpr.proc);
7964                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7965                    // NOTE: there is still a race here where a signal could be
7966                    // pending on the process even though we managed to update its
7967                    // adj level.  Not sure what to do about this, but at least
7968                    // the race is now smaller.
7969                    if (!success) {
7970                        // Uh oh...  it looks like the provider's process
7971                        // has been killed on us.  We need to wait for a new
7972                        // process to be started, and make sure its death
7973                        // doesn't kill our process.
7974                        Slog.i(TAG,
7975                                "Existing provider " + cpr.name.flattenToShortString()
7976                                + " is crashing; detaching " + r);
7977                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7978                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7979                        if (!lastRef) {
7980                            // This wasn't the last ref our process had on
7981                            // the provider...  we have now been killed, bail.
7982                            return null;
7983                        }
7984                        providerRunning = false;
7985                        conn = null;
7986                    }
7987                }
7988
7989                Binder.restoreCallingIdentity(origId);
7990            }
7991
7992            boolean singleton;
7993            if (!providerRunning) {
7994                try {
7995                    cpi = AppGlobals.getPackageManager().
7996                        resolveContentProvider(name,
7997                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7998                } catch (RemoteException ex) {
7999                }
8000                if (cpi == null) {
8001                    return null;
8002                }
8003                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8004                        cpi.name, cpi.flags);
8005                if (singleton) {
8006                    userId = 0;
8007                }
8008                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8009
8010                String msg;
8011                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
8012                    throw new SecurityException(msg);
8013                }
8014
8015                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8016                        && !cpi.processName.equals("system")) {
8017                    // If this content provider does not run in the system
8018                    // process, and the system is not yet ready to run other
8019                    // processes, then fail fast instead of hanging.
8020                    throw new IllegalArgumentException(
8021                            "Attempt to launch content provider before system ready");
8022                }
8023
8024                // Make sure that the user who owns this provider is started.  If not,
8025                // we don't want to allow it to run.
8026                if (mStartedUsers.get(userId) == null) {
8027                    Slog.w(TAG, "Unable to launch app "
8028                            + cpi.applicationInfo.packageName + "/"
8029                            + cpi.applicationInfo.uid + " for provider "
8030                            + name + ": user " + userId + " is stopped");
8031                    return null;
8032                }
8033
8034                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8035                cpr = mProviderMap.getProviderByClass(comp, userId);
8036                final boolean firstClass = cpr == null;
8037                if (firstClass) {
8038                    try {
8039                        ApplicationInfo ai =
8040                            AppGlobals.getPackageManager().
8041                                getApplicationInfo(
8042                                        cpi.applicationInfo.packageName,
8043                                        STOCK_PM_FLAGS, userId);
8044                        if (ai == null) {
8045                            Slog.w(TAG, "No package info for content provider "
8046                                    + cpi.name);
8047                            return null;
8048                        }
8049                        ai = getAppInfoForUser(ai, userId);
8050                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8051                    } catch (RemoteException ex) {
8052                        // pm is in same process, this will never happen.
8053                    }
8054                }
8055
8056                if (r != null && cpr.canRunHere(r)) {
8057                    // If this is a multiprocess provider, then just return its
8058                    // info and allow the caller to instantiate it.  Only do
8059                    // this if the provider is the same user as the caller's
8060                    // process, or can run as root (so can be in any process).
8061                    return cpr.newHolder(null);
8062                }
8063
8064                if (DEBUG_PROVIDER) {
8065                    RuntimeException e = new RuntimeException("here");
8066                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8067                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8068                }
8069
8070                // This is single process, and our app is now connecting to it.
8071                // See if we are already in the process of launching this
8072                // provider.
8073                final int N = mLaunchingProviders.size();
8074                int i;
8075                for (i=0; i<N; i++) {
8076                    if (mLaunchingProviders.get(i) == cpr) {
8077                        break;
8078                    }
8079                }
8080
8081                // If the provider is not already being launched, then get it
8082                // started.
8083                if (i >= N) {
8084                    final long origId = Binder.clearCallingIdentity();
8085
8086                    try {
8087                        // Content provider is now in use, its package can't be stopped.
8088                        try {
8089                            AppGlobals.getPackageManager().setPackageStoppedState(
8090                                    cpr.appInfo.packageName, false, userId);
8091                        } catch (RemoteException e) {
8092                        } catch (IllegalArgumentException e) {
8093                            Slog.w(TAG, "Failed trying to unstop package "
8094                                    + cpr.appInfo.packageName + ": " + e);
8095                        }
8096
8097                        // Use existing process if already started
8098                        ProcessRecord proc = getProcessRecordLocked(
8099                                cpi.processName, cpr.appInfo.uid, false);
8100                        if (proc != null && proc.thread != null) {
8101                            if (DEBUG_PROVIDER) {
8102                                Slog.d(TAG, "Installing in existing process " + proc);
8103                            }
8104                            proc.pubProviders.put(cpi.name, cpr);
8105                            try {
8106                                proc.thread.scheduleInstallProvider(cpi);
8107                            } catch (RemoteException e) {
8108                            }
8109                        } else {
8110                            proc = startProcessLocked(cpi.processName,
8111                                    cpr.appInfo, false, 0, "content provider",
8112                                    new ComponentName(cpi.applicationInfo.packageName,
8113                                            cpi.name), false, false, false);
8114                            if (proc == null) {
8115                                Slog.w(TAG, "Unable to launch app "
8116                                        + cpi.applicationInfo.packageName + "/"
8117                                        + cpi.applicationInfo.uid + " for provider "
8118                                        + name + ": process is bad");
8119                                return null;
8120                            }
8121                        }
8122                        cpr.launchingApp = proc;
8123                        mLaunchingProviders.add(cpr);
8124                    } finally {
8125                        Binder.restoreCallingIdentity(origId);
8126                    }
8127                }
8128
8129                // Make sure the provider is published (the same provider class
8130                // may be published under multiple names).
8131                if (firstClass) {
8132                    mProviderMap.putProviderByClass(comp, cpr);
8133                }
8134
8135                mProviderMap.putProviderByName(name, cpr);
8136                conn = incProviderCountLocked(r, cpr, token, stable);
8137                if (conn != null) {
8138                    conn.waiting = true;
8139                }
8140            }
8141        }
8142
8143        // Wait for the provider to be published...
8144        synchronized (cpr) {
8145            while (cpr.provider == null) {
8146                if (cpr.launchingApp == null) {
8147                    Slog.w(TAG, "Unable to launch app "
8148                            + cpi.applicationInfo.packageName + "/"
8149                            + cpi.applicationInfo.uid + " for provider "
8150                            + name + ": launching app became null");
8151                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8152                            UserHandle.getUserId(cpi.applicationInfo.uid),
8153                            cpi.applicationInfo.packageName,
8154                            cpi.applicationInfo.uid, name);
8155                    return null;
8156                }
8157                try {
8158                    if (DEBUG_MU) {
8159                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8160                                + cpr.launchingApp);
8161                    }
8162                    if (conn != null) {
8163                        conn.waiting = true;
8164                    }
8165                    cpr.wait();
8166                } catch (InterruptedException ex) {
8167                } finally {
8168                    if (conn != null) {
8169                        conn.waiting = false;
8170                    }
8171                }
8172            }
8173        }
8174        return cpr != null ? cpr.newHolder(conn) : null;
8175    }
8176
8177    @Override
8178    public final ContentProviderHolder getContentProvider(
8179            IApplicationThread caller, String name, int userId, boolean stable) {
8180        enforceNotIsolatedCaller("getContentProvider");
8181        if (caller == null) {
8182            String msg = "null IApplicationThread when getting content provider "
8183                    + name;
8184            Slog.w(TAG, msg);
8185            throw new SecurityException(msg);
8186        }
8187        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8188        // with cross-user grant.
8189        return getContentProviderImpl(caller, name, null, stable, userId);
8190    }
8191
8192    public ContentProviderHolder getContentProviderExternal(
8193            String name, int userId, IBinder token) {
8194        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8195            "Do not have permission in call getContentProviderExternal()");
8196        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8197                false, true, "getContentProvider", null);
8198        return getContentProviderExternalUnchecked(name, token, userId);
8199    }
8200
8201    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8202            IBinder token, int userId) {
8203        return getContentProviderImpl(null, name, token, true, userId);
8204    }
8205
8206    /**
8207     * Drop a content provider from a ProcessRecord's bookkeeping
8208     */
8209    public void removeContentProvider(IBinder connection, boolean stable) {
8210        enforceNotIsolatedCaller("removeContentProvider");
8211        long ident = Binder.clearCallingIdentity();
8212        try {
8213            synchronized (this) {
8214                ContentProviderConnection conn;
8215                try {
8216                    conn = (ContentProviderConnection)connection;
8217                } catch (ClassCastException e) {
8218                    String msg ="removeContentProvider: " + connection
8219                            + " not a ContentProviderConnection";
8220                    Slog.w(TAG, msg);
8221                    throw new IllegalArgumentException(msg);
8222                }
8223                if (conn == null) {
8224                    throw new NullPointerException("connection is null");
8225                }
8226                if (decProviderCountLocked(conn, null, null, stable)) {
8227                    updateOomAdjLocked();
8228                }
8229            }
8230        } finally {
8231            Binder.restoreCallingIdentity(ident);
8232        }
8233    }
8234
8235    public void removeContentProviderExternal(String name, IBinder token) {
8236        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8237            "Do not have permission in call removeContentProviderExternal()");
8238        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8239    }
8240
8241    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8242        synchronized (this) {
8243            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8244            if(cpr == null) {
8245                //remove from mProvidersByClass
8246                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8247                return;
8248            }
8249
8250            //update content provider record entry info
8251            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8252            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8253            if (localCpr.hasExternalProcessHandles()) {
8254                if (localCpr.removeExternalProcessHandleLocked(token)) {
8255                    updateOomAdjLocked();
8256                } else {
8257                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8258                            + " with no external reference for token: "
8259                            + token + ".");
8260                }
8261            } else {
8262                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8263                        + " with no external references.");
8264            }
8265        }
8266    }
8267
8268    public final void publishContentProviders(IApplicationThread caller,
8269            List<ContentProviderHolder> providers) {
8270        if (providers == null) {
8271            return;
8272        }
8273
8274        enforceNotIsolatedCaller("publishContentProviders");
8275        synchronized (this) {
8276            final ProcessRecord r = getRecordForAppLocked(caller);
8277            if (DEBUG_MU)
8278                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8279            if (r == null) {
8280                throw new SecurityException(
8281                        "Unable to find app for caller " + caller
8282                      + " (pid=" + Binder.getCallingPid()
8283                      + ") when publishing content providers");
8284            }
8285
8286            final long origId = Binder.clearCallingIdentity();
8287
8288            final int N = providers.size();
8289            for (int i=0; i<N; i++) {
8290                ContentProviderHolder src = providers.get(i);
8291                if (src == null || src.info == null || src.provider == null) {
8292                    continue;
8293                }
8294                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8295                if (DEBUG_MU)
8296                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8297                if (dst != null) {
8298                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8299                    mProviderMap.putProviderByClass(comp, dst);
8300                    String names[] = dst.info.authority.split(";");
8301                    for (int j = 0; j < names.length; j++) {
8302                        mProviderMap.putProviderByName(names[j], dst);
8303                    }
8304
8305                    int NL = mLaunchingProviders.size();
8306                    int j;
8307                    for (j=0; j<NL; j++) {
8308                        if (mLaunchingProviders.get(j) == dst) {
8309                            mLaunchingProviders.remove(j);
8310                            j--;
8311                            NL--;
8312                        }
8313                    }
8314                    synchronized (dst) {
8315                        dst.provider = src.provider;
8316                        dst.proc = r;
8317                        dst.notifyAll();
8318                    }
8319                    updateOomAdjLocked(r);
8320                }
8321            }
8322
8323            Binder.restoreCallingIdentity(origId);
8324        }
8325    }
8326
8327    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8328        ContentProviderConnection conn;
8329        try {
8330            conn = (ContentProviderConnection)connection;
8331        } catch (ClassCastException e) {
8332            String msg ="refContentProvider: " + connection
8333                    + " not a ContentProviderConnection";
8334            Slog.w(TAG, msg);
8335            throw new IllegalArgumentException(msg);
8336        }
8337        if (conn == null) {
8338            throw new NullPointerException("connection is null");
8339        }
8340
8341        synchronized (this) {
8342            if (stable > 0) {
8343                conn.numStableIncs += stable;
8344            }
8345            stable = conn.stableCount + stable;
8346            if (stable < 0) {
8347                throw new IllegalStateException("stableCount < 0: " + stable);
8348            }
8349
8350            if (unstable > 0) {
8351                conn.numUnstableIncs += unstable;
8352            }
8353            unstable = conn.unstableCount + unstable;
8354            if (unstable < 0) {
8355                throw new IllegalStateException("unstableCount < 0: " + unstable);
8356            }
8357
8358            if ((stable+unstable) <= 0) {
8359                throw new IllegalStateException("ref counts can't go to zero here: stable="
8360                        + stable + " unstable=" + unstable);
8361            }
8362            conn.stableCount = stable;
8363            conn.unstableCount = unstable;
8364            return !conn.dead;
8365        }
8366    }
8367
8368    public void unstableProviderDied(IBinder connection) {
8369        ContentProviderConnection conn;
8370        try {
8371            conn = (ContentProviderConnection)connection;
8372        } catch (ClassCastException e) {
8373            String msg ="refContentProvider: " + connection
8374                    + " not a ContentProviderConnection";
8375            Slog.w(TAG, msg);
8376            throw new IllegalArgumentException(msg);
8377        }
8378        if (conn == null) {
8379            throw new NullPointerException("connection is null");
8380        }
8381
8382        // Safely retrieve the content provider associated with the connection.
8383        IContentProvider provider;
8384        synchronized (this) {
8385            provider = conn.provider.provider;
8386        }
8387
8388        if (provider == null) {
8389            // Um, yeah, we're way ahead of you.
8390            return;
8391        }
8392
8393        // Make sure the caller is being honest with us.
8394        if (provider.asBinder().pingBinder()) {
8395            // Er, no, still looks good to us.
8396            synchronized (this) {
8397                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8398                        + " says " + conn + " died, but we don't agree");
8399                return;
8400            }
8401        }
8402
8403        // Well look at that!  It's dead!
8404        synchronized (this) {
8405            if (conn.provider.provider != provider) {
8406                // But something changed...  good enough.
8407                return;
8408            }
8409
8410            ProcessRecord proc = conn.provider.proc;
8411            if (proc == null || proc.thread == null) {
8412                // Seems like the process is already cleaned up.
8413                return;
8414            }
8415
8416            // As far as we're concerned, this is just like receiving a
8417            // death notification...  just a bit prematurely.
8418            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8419                    + ") early provider death");
8420            final long ident = Binder.clearCallingIdentity();
8421            try {
8422                appDiedLocked(proc, proc.pid, proc.thread);
8423            } finally {
8424                Binder.restoreCallingIdentity(ident);
8425            }
8426        }
8427    }
8428
8429    @Override
8430    public void appNotRespondingViaProvider(IBinder connection) {
8431        enforceCallingPermission(
8432                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8433
8434        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8435        if (conn == null) {
8436            Slog.w(TAG, "ContentProviderConnection is null");
8437            return;
8438        }
8439
8440        final ProcessRecord host = conn.provider.proc;
8441        if (host == null) {
8442            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8443            return;
8444        }
8445
8446        final long token = Binder.clearCallingIdentity();
8447        try {
8448            appNotResponding(host, null, null, false, "ContentProvider not responding");
8449        } finally {
8450            Binder.restoreCallingIdentity(token);
8451        }
8452    }
8453
8454    public final void installSystemProviders() {
8455        List<ProviderInfo> providers;
8456        synchronized (this) {
8457            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8458            providers = generateApplicationProvidersLocked(app);
8459            if (providers != null) {
8460                for (int i=providers.size()-1; i>=0; i--) {
8461                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8462                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8463                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8464                                + ": not system .apk");
8465                        providers.remove(i);
8466                    }
8467                }
8468            }
8469        }
8470        if (providers != null) {
8471            mSystemThread.installSystemProviders(providers);
8472        }
8473
8474        mCoreSettingsObserver = new CoreSettingsObserver(this);
8475
8476        mUsageStatsService.monitorPackages();
8477    }
8478
8479    /**
8480     * Allows app to retrieve the MIME type of a URI without having permission
8481     * to access its content provider.
8482     *
8483     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8484     *
8485     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8486     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8487     */
8488    public String getProviderMimeType(Uri uri, int userId) {
8489        enforceNotIsolatedCaller("getProviderMimeType");
8490        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8491                userId, false, true, "getProviderMimeType", null);
8492        final String name = uri.getAuthority();
8493        final long ident = Binder.clearCallingIdentity();
8494        ContentProviderHolder holder = null;
8495
8496        try {
8497            holder = getContentProviderExternalUnchecked(name, null, userId);
8498            if (holder != null) {
8499                return holder.provider.getType(uri);
8500            }
8501        } catch (RemoteException e) {
8502            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8503            return null;
8504        } finally {
8505            if (holder != null) {
8506                removeContentProviderExternalUnchecked(name, null, userId);
8507            }
8508            Binder.restoreCallingIdentity(ident);
8509        }
8510
8511        return null;
8512    }
8513
8514    // =========================================================
8515    // GLOBAL MANAGEMENT
8516    // =========================================================
8517
8518    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8519            boolean isolated) {
8520        String proc = customProcess != null ? customProcess : info.processName;
8521        BatteryStatsImpl.Uid.Proc ps = null;
8522        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8523        int uid = info.uid;
8524        if (isolated) {
8525            int userId = UserHandle.getUserId(uid);
8526            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8527            while (true) {
8528                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8529                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8530                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8531                }
8532                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8533                mNextIsolatedProcessUid++;
8534                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8535                    // No process for this uid, use it.
8536                    break;
8537                }
8538                stepsLeft--;
8539                if (stepsLeft <= 0) {
8540                    return null;
8541                }
8542            }
8543        }
8544        return new ProcessRecord(stats, info, proc, uid);
8545    }
8546
8547    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8548        ProcessRecord app;
8549        if (!isolated) {
8550            app = getProcessRecordLocked(info.processName, info.uid, true);
8551        } else {
8552            app = null;
8553        }
8554
8555        if (app == null) {
8556            app = newProcessRecordLocked(info, null, isolated);
8557            mProcessNames.put(info.processName, app.uid, app);
8558            if (isolated) {
8559                mIsolatedProcesses.put(app.uid, app);
8560            }
8561            updateLruProcessLocked(app, false, null);
8562            updateOomAdjLocked();
8563        }
8564
8565        // This package really, really can not be stopped.
8566        try {
8567            AppGlobals.getPackageManager().setPackageStoppedState(
8568                    info.packageName, false, UserHandle.getUserId(app.uid));
8569        } catch (RemoteException e) {
8570        } catch (IllegalArgumentException e) {
8571            Slog.w(TAG, "Failed trying to unstop package "
8572                    + info.packageName + ": " + e);
8573        }
8574
8575        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8576                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8577            app.persistent = true;
8578            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8579        }
8580        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8581            mPersistentStartingProcesses.add(app);
8582            startProcessLocked(app, "added application", app.processName);
8583        }
8584
8585        return app;
8586    }
8587
8588    public void unhandledBack() {
8589        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8590                "unhandledBack()");
8591
8592        synchronized(this) {
8593            final long origId = Binder.clearCallingIdentity();
8594            try {
8595                getFocusedStack().unhandledBackLocked();
8596            } finally {
8597                Binder.restoreCallingIdentity(origId);
8598            }
8599        }
8600    }
8601
8602    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8603        enforceNotIsolatedCaller("openContentUri");
8604        final int userId = UserHandle.getCallingUserId();
8605        String name = uri.getAuthority();
8606        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8607        ParcelFileDescriptor pfd = null;
8608        if (cph != null) {
8609            // We record the binder invoker's uid in thread-local storage before
8610            // going to the content provider to open the file.  Later, in the code
8611            // that handles all permissions checks, we look for this uid and use
8612            // that rather than the Activity Manager's own uid.  The effect is that
8613            // we do the check against the caller's permissions even though it looks
8614            // to the content provider like the Activity Manager itself is making
8615            // the request.
8616            sCallerIdentity.set(new Identity(
8617                    Binder.getCallingPid(), Binder.getCallingUid()));
8618            try {
8619                pfd = cph.provider.openFile(null, uri, "r", null);
8620            } catch (FileNotFoundException e) {
8621                // do nothing; pfd will be returned null
8622            } finally {
8623                // Ensure that whatever happens, we clean up the identity state
8624                sCallerIdentity.remove();
8625            }
8626
8627            // We've got the fd now, so we're done with the provider.
8628            removeContentProviderExternalUnchecked(name, null, userId);
8629        } else {
8630            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8631        }
8632        return pfd;
8633    }
8634
8635    // Actually is sleeping or shutting down or whatever else in the future
8636    // is an inactive state.
8637    public boolean isSleepingOrShuttingDown() {
8638        return mSleeping || mShuttingDown;
8639    }
8640
8641    public boolean isSleeping() {
8642        return mSleeping;
8643    }
8644
8645    void goingToSleep() {
8646        synchronized(this) {
8647            mWentToSleep = true;
8648            updateEventDispatchingLocked();
8649            goToSleepIfNeededLocked();
8650        }
8651    }
8652
8653    void finishRunningVoiceLocked() {
8654        if (mRunningVoice) {
8655            mRunningVoice = false;
8656            goToSleepIfNeededLocked();
8657        }
8658    }
8659
8660    void goToSleepIfNeededLocked() {
8661        if (mWentToSleep && !mRunningVoice) {
8662            if (!mSleeping) {
8663                mSleeping = true;
8664                mStackSupervisor.goingToSleepLocked();
8665
8666                // Initialize the wake times of all processes.
8667                checkExcessivePowerUsageLocked(false);
8668                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8669                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8670                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8671            }
8672        }
8673    }
8674
8675    @Override
8676    public boolean shutdown(int timeout) {
8677        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8678                != PackageManager.PERMISSION_GRANTED) {
8679            throw new SecurityException("Requires permission "
8680                    + android.Manifest.permission.SHUTDOWN);
8681        }
8682
8683        boolean timedout = false;
8684
8685        synchronized(this) {
8686            mShuttingDown = true;
8687            updateEventDispatchingLocked();
8688            timedout = mStackSupervisor.shutdownLocked(timeout);
8689        }
8690
8691        mAppOpsService.shutdown();
8692        mUsageStatsService.shutdown();
8693        mBatteryStatsService.shutdown();
8694        synchronized (this) {
8695            mProcessStats.shutdownLocked();
8696        }
8697
8698        return timedout;
8699    }
8700
8701    public final void activitySlept(IBinder token) {
8702        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8703
8704        final long origId = Binder.clearCallingIdentity();
8705
8706        synchronized (this) {
8707            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8708            if (r != null) {
8709                mStackSupervisor.activitySleptLocked(r);
8710            }
8711        }
8712
8713        Binder.restoreCallingIdentity(origId);
8714    }
8715
8716    void logLockScreen(String msg) {
8717        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8718                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8719                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8720                mStackSupervisor.mDismissKeyguardOnNextActivity);
8721    }
8722
8723    private void comeOutOfSleepIfNeededLocked() {
8724        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8725            if (mSleeping) {
8726                mSleeping = false;
8727                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8728            }
8729        }
8730    }
8731
8732    void wakingUp() {
8733        synchronized(this) {
8734            mWentToSleep = false;
8735            updateEventDispatchingLocked();
8736            comeOutOfSleepIfNeededLocked();
8737        }
8738    }
8739
8740    void startRunningVoiceLocked() {
8741        if (!mRunningVoice) {
8742            mRunningVoice = true;
8743            comeOutOfSleepIfNeededLocked();
8744        }
8745    }
8746
8747    private void updateEventDispatchingLocked() {
8748        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8749    }
8750
8751    public void setLockScreenShown(boolean shown) {
8752        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8753                != PackageManager.PERMISSION_GRANTED) {
8754            throw new SecurityException("Requires permission "
8755                    + android.Manifest.permission.DEVICE_POWER);
8756        }
8757
8758        synchronized(this) {
8759            long ident = Binder.clearCallingIdentity();
8760            try {
8761                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8762                mLockScreenShown = shown;
8763                comeOutOfSleepIfNeededLocked();
8764            } finally {
8765                Binder.restoreCallingIdentity(ident);
8766            }
8767        }
8768    }
8769
8770    public void stopAppSwitches() {
8771        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8772                != PackageManager.PERMISSION_GRANTED) {
8773            throw new SecurityException("Requires permission "
8774                    + android.Manifest.permission.STOP_APP_SWITCHES);
8775        }
8776
8777        synchronized(this) {
8778            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8779                    + APP_SWITCH_DELAY_TIME;
8780            mDidAppSwitch = false;
8781            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8782            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8783            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8784        }
8785    }
8786
8787    public void resumeAppSwitches() {
8788        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8789                != PackageManager.PERMISSION_GRANTED) {
8790            throw new SecurityException("Requires permission "
8791                    + android.Manifest.permission.STOP_APP_SWITCHES);
8792        }
8793
8794        synchronized(this) {
8795            // Note that we don't execute any pending app switches... we will
8796            // let those wait until either the timeout, or the next start
8797            // activity request.
8798            mAppSwitchesAllowedTime = 0;
8799        }
8800    }
8801
8802    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8803            String name) {
8804        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8805            return true;
8806        }
8807
8808        final int perm = checkComponentPermission(
8809                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8810                callingUid, -1, true);
8811        if (perm == PackageManager.PERMISSION_GRANTED) {
8812            return true;
8813        }
8814
8815        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8816        return false;
8817    }
8818
8819    public void setDebugApp(String packageName, boolean waitForDebugger,
8820            boolean persistent) {
8821        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8822                "setDebugApp()");
8823
8824        long ident = Binder.clearCallingIdentity();
8825        try {
8826            // Note that this is not really thread safe if there are multiple
8827            // callers into it at the same time, but that's not a situation we
8828            // care about.
8829            if (persistent) {
8830                final ContentResolver resolver = mContext.getContentResolver();
8831                Settings.Global.putString(
8832                    resolver, Settings.Global.DEBUG_APP,
8833                    packageName);
8834                Settings.Global.putInt(
8835                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8836                    waitForDebugger ? 1 : 0);
8837            }
8838
8839            synchronized (this) {
8840                if (!persistent) {
8841                    mOrigDebugApp = mDebugApp;
8842                    mOrigWaitForDebugger = mWaitForDebugger;
8843                }
8844                mDebugApp = packageName;
8845                mWaitForDebugger = waitForDebugger;
8846                mDebugTransient = !persistent;
8847                if (packageName != null) {
8848                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8849                            false, UserHandle.USER_ALL, "set debug app");
8850                }
8851            }
8852        } finally {
8853            Binder.restoreCallingIdentity(ident);
8854        }
8855    }
8856
8857    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8858        synchronized (this) {
8859            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8860            if (!isDebuggable) {
8861                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8862                    throw new SecurityException("Process not debuggable: " + app.packageName);
8863                }
8864            }
8865
8866            mOpenGlTraceApp = processName;
8867        }
8868    }
8869
8870    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8871            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8872        synchronized (this) {
8873            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8874            if (!isDebuggable) {
8875                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8876                    throw new SecurityException("Process not debuggable: " + app.packageName);
8877                }
8878            }
8879            mProfileApp = processName;
8880            mProfileFile = profileFile;
8881            if (mProfileFd != null) {
8882                try {
8883                    mProfileFd.close();
8884                } catch (IOException e) {
8885                }
8886                mProfileFd = null;
8887            }
8888            mProfileFd = profileFd;
8889            mProfileType = 0;
8890            mAutoStopProfiler = autoStopProfiler;
8891        }
8892    }
8893
8894    @Override
8895    public void setAlwaysFinish(boolean enabled) {
8896        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8897                "setAlwaysFinish()");
8898
8899        Settings.Global.putInt(
8900                mContext.getContentResolver(),
8901                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8902
8903        synchronized (this) {
8904            mAlwaysFinishActivities = enabled;
8905        }
8906    }
8907
8908    @Override
8909    public void setActivityController(IActivityController controller) {
8910        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8911                "setActivityController()");
8912        synchronized (this) {
8913            mController = controller;
8914            Watchdog.getInstance().setActivityController(controller);
8915        }
8916    }
8917
8918    @Override
8919    public void setUserIsMonkey(boolean userIsMonkey) {
8920        synchronized (this) {
8921            synchronized (mPidsSelfLocked) {
8922                final int callingPid = Binder.getCallingPid();
8923                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8924                if (precessRecord == null) {
8925                    throw new SecurityException("Unknown process: " + callingPid);
8926                }
8927                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8928                    throw new SecurityException("Only an instrumentation process "
8929                            + "with a UiAutomation can call setUserIsMonkey");
8930                }
8931            }
8932            mUserIsMonkey = userIsMonkey;
8933        }
8934    }
8935
8936    @Override
8937    public boolean isUserAMonkey() {
8938        synchronized (this) {
8939            // If there is a controller also implies the user is a monkey.
8940            return (mUserIsMonkey || mController != null);
8941        }
8942    }
8943
8944    public void requestBugReport() {
8945        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8946        SystemProperties.set("ctl.start", "bugreport");
8947    }
8948
8949    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8950        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8951    }
8952
8953    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8954        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8955            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8956        }
8957        return KEY_DISPATCHING_TIMEOUT;
8958    }
8959
8960    @Override
8961    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8962        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8963                != PackageManager.PERMISSION_GRANTED) {
8964            throw new SecurityException("Requires permission "
8965                    + android.Manifest.permission.FILTER_EVENTS);
8966        }
8967        ProcessRecord proc;
8968        long timeout;
8969        synchronized (this) {
8970            synchronized (mPidsSelfLocked) {
8971                proc = mPidsSelfLocked.get(pid);
8972            }
8973            timeout = getInputDispatchingTimeoutLocked(proc);
8974        }
8975
8976        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8977            return -1;
8978        }
8979
8980        return timeout;
8981    }
8982
8983    /**
8984     * Handle input dispatching timeouts.
8985     * Returns whether input dispatching should be aborted or not.
8986     */
8987    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8988            final ActivityRecord activity, final ActivityRecord parent,
8989            final boolean aboveSystem, String reason) {
8990        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8991                != PackageManager.PERMISSION_GRANTED) {
8992            throw new SecurityException("Requires permission "
8993                    + android.Manifest.permission.FILTER_EVENTS);
8994        }
8995
8996        final String annotation;
8997        if (reason == null) {
8998            annotation = "Input dispatching timed out";
8999        } else {
9000            annotation = "Input dispatching timed out (" + reason + ")";
9001        }
9002
9003        if (proc != null) {
9004            synchronized (this) {
9005                if (proc.debugging) {
9006                    return false;
9007                }
9008
9009                if (mDidDexOpt) {
9010                    // Give more time since we were dexopting.
9011                    mDidDexOpt = false;
9012                    return false;
9013                }
9014
9015                if (proc.instrumentationClass != null) {
9016                    Bundle info = new Bundle();
9017                    info.putString("shortMsg", "keyDispatchingTimedOut");
9018                    info.putString("longMsg", annotation);
9019                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9020                    return true;
9021                }
9022            }
9023            mHandler.post(new Runnable() {
9024                @Override
9025                public void run() {
9026                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9027                }
9028            });
9029        }
9030
9031        return true;
9032    }
9033
9034    public Bundle getAssistContextExtras(int requestType) {
9035        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9036                "getAssistContextExtras()");
9037        PendingAssistExtras pae;
9038        Bundle extras = new Bundle();
9039        synchronized (this) {
9040            ActivityRecord activity = getFocusedStack().mResumedActivity;
9041            if (activity == null) {
9042                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9043                return null;
9044            }
9045            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9046            if (activity.app == null || activity.app.thread == null) {
9047                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9048                return extras;
9049            }
9050            if (activity.app.pid == Binder.getCallingPid()) {
9051                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9052                return extras;
9053            }
9054            pae = new PendingAssistExtras(activity);
9055            try {
9056                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9057                        requestType);
9058                mPendingAssistExtras.add(pae);
9059                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9060            } catch (RemoteException e) {
9061                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9062                return extras;
9063            }
9064        }
9065        synchronized (pae) {
9066            while (!pae.haveResult) {
9067                try {
9068                    pae.wait();
9069                } catch (InterruptedException e) {
9070                }
9071            }
9072            if (pae.result != null) {
9073                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9074            }
9075        }
9076        synchronized (this) {
9077            mPendingAssistExtras.remove(pae);
9078            mHandler.removeCallbacks(pae);
9079        }
9080        return extras;
9081    }
9082
9083    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9084        PendingAssistExtras pae = (PendingAssistExtras)token;
9085        synchronized (pae) {
9086            pae.result = extras;
9087            pae.haveResult = true;
9088            pae.notifyAll();
9089        }
9090    }
9091
9092    public void registerProcessObserver(IProcessObserver observer) {
9093        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9094                "registerProcessObserver()");
9095        synchronized (this) {
9096            mProcessObservers.register(observer);
9097        }
9098    }
9099
9100    @Override
9101    public void unregisterProcessObserver(IProcessObserver observer) {
9102        synchronized (this) {
9103            mProcessObservers.unregister(observer);
9104        }
9105    }
9106
9107    @Override
9108    public boolean convertFromTranslucent(IBinder token) {
9109        final long origId = Binder.clearCallingIdentity();
9110        try {
9111            synchronized (this) {
9112                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9113                if (r == null) {
9114                    return false;
9115                }
9116                if (r.changeWindowTranslucency(true)) {
9117                    mWindowManager.setAppFullscreen(token, true);
9118                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9119                    return true;
9120                }
9121                return false;
9122            }
9123        } finally {
9124            Binder.restoreCallingIdentity(origId);
9125        }
9126    }
9127
9128    @Override
9129    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9130        final long origId = Binder.clearCallingIdentity();
9131        try {
9132            synchronized (this) {
9133                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9134                if (r == null) {
9135                    return false;
9136                }
9137                if (r.changeWindowTranslucency(false)) {
9138                    r.task.stack.convertToTranslucent(r, options);
9139                    mWindowManager.setAppFullscreen(token, false);
9140                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9141                    return true;
9142                }
9143                return false;
9144            }
9145        } finally {
9146            Binder.restoreCallingIdentity(origId);
9147        }
9148    }
9149
9150    @Override
9151    public ActivityOptions getActivityOptions(IBinder token) {
9152        final long origId = Binder.clearCallingIdentity();
9153        try {
9154            synchronized (this) {
9155                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9156                if (r != null) {
9157                    final ActivityOptions activityOptions = r.pendingOptions;
9158                    r.pendingOptions = null;
9159                    return activityOptions;
9160                }
9161                return null;
9162            }
9163        } finally {
9164            Binder.restoreCallingIdentity(origId);
9165        }
9166    }
9167
9168    @Override
9169    public void setImmersive(IBinder token, boolean immersive) {
9170        synchronized(this) {
9171            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9172            if (r == null) {
9173                throw new IllegalArgumentException();
9174            }
9175            r.immersive = immersive;
9176
9177            // update associated state if we're frontmost
9178            if (r == mFocusedActivity) {
9179                if (DEBUG_IMMERSIVE) {
9180                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9181                }
9182                applyUpdateLockStateLocked(r);
9183            }
9184        }
9185    }
9186
9187    @Override
9188    public boolean isImmersive(IBinder token) {
9189        synchronized (this) {
9190            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9191            if (r == null) {
9192                throw new IllegalArgumentException();
9193            }
9194            return r.immersive;
9195        }
9196    }
9197
9198    public boolean isTopActivityImmersive() {
9199        enforceNotIsolatedCaller("startActivity");
9200        synchronized (this) {
9201            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9202            return (r != null) ? r.immersive : false;
9203        }
9204    }
9205
9206    public final void enterSafeMode() {
9207        synchronized(this) {
9208            // It only makes sense to do this before the system is ready
9209            // and started launching other packages.
9210            if (!mSystemReady) {
9211                try {
9212                    AppGlobals.getPackageManager().enterSafeMode();
9213                } catch (RemoteException e) {
9214                }
9215            }
9216
9217            mSafeMode = true;
9218        }
9219    }
9220
9221    public final void showSafeModeOverlay() {
9222        View v = LayoutInflater.from(mContext).inflate(
9223                com.android.internal.R.layout.safe_mode, null);
9224        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9225        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9226        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9227        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9228        lp.gravity = Gravity.BOTTOM | Gravity.START;
9229        lp.format = v.getBackground().getOpacity();
9230        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9231                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9232        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9233        ((WindowManager)mContext.getSystemService(
9234                Context.WINDOW_SERVICE)).addView(v, lp);
9235    }
9236
9237    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9238        if (!(sender instanceof PendingIntentRecord)) {
9239            return;
9240        }
9241        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9242        synchronized (stats) {
9243            if (mBatteryStatsService.isOnBattery()) {
9244                mBatteryStatsService.enforceCallingPermission();
9245                PendingIntentRecord rec = (PendingIntentRecord)sender;
9246                int MY_UID = Binder.getCallingUid();
9247                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9248                BatteryStatsImpl.Uid.Pkg pkg =
9249                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9250                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9251                pkg.incWakeupsLocked();
9252            }
9253        }
9254    }
9255
9256    public boolean killPids(int[] pids, String pReason, boolean secure) {
9257        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9258            throw new SecurityException("killPids only available to the system");
9259        }
9260        String reason = (pReason == null) ? "Unknown" : pReason;
9261        // XXX Note: don't acquire main activity lock here, because the window
9262        // manager calls in with its locks held.
9263
9264        boolean killed = false;
9265        synchronized (mPidsSelfLocked) {
9266            int[] types = new int[pids.length];
9267            int worstType = 0;
9268            for (int i=0; i<pids.length; i++) {
9269                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9270                if (proc != null) {
9271                    int type = proc.setAdj;
9272                    types[i] = type;
9273                    if (type > worstType) {
9274                        worstType = type;
9275                    }
9276                }
9277            }
9278
9279            // If the worst oom_adj is somewhere in the cached proc LRU range,
9280            // then constrain it so we will kill all cached procs.
9281            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9282                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9283                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9284            }
9285
9286            // If this is not a secure call, don't let it kill processes that
9287            // are important.
9288            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9289                worstType = ProcessList.SERVICE_ADJ;
9290            }
9291
9292            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9293            for (int i=0; i<pids.length; i++) {
9294                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9295                if (proc == null) {
9296                    continue;
9297                }
9298                int adj = proc.setAdj;
9299                if (adj >= worstType && !proc.killedByAm) {
9300                    killUnneededProcessLocked(proc, reason);
9301                    killed = true;
9302                }
9303            }
9304        }
9305        return killed;
9306    }
9307
9308    @Override
9309    public void killUid(int uid, String reason) {
9310        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9311            throw new SecurityException("killUid only available to the system");
9312        }
9313        synchronized (this) {
9314            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9315                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9316                    reason != null ? reason : "kill uid");
9317        }
9318    }
9319
9320    @Override
9321    public boolean killProcessesBelowForeground(String reason) {
9322        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9323            throw new SecurityException("killProcessesBelowForeground() only available to system");
9324        }
9325
9326        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9327    }
9328
9329    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9330        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9331            throw new SecurityException("killProcessesBelowAdj() only available to system");
9332        }
9333
9334        boolean killed = false;
9335        synchronized (mPidsSelfLocked) {
9336            final int size = mPidsSelfLocked.size();
9337            for (int i = 0; i < size; i++) {
9338                final int pid = mPidsSelfLocked.keyAt(i);
9339                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9340                if (proc == null) continue;
9341
9342                final int adj = proc.setAdj;
9343                if (adj > belowAdj && !proc.killedByAm) {
9344                    killUnneededProcessLocked(proc, reason);
9345                    killed = true;
9346                }
9347            }
9348        }
9349        return killed;
9350    }
9351
9352    @Override
9353    public void hang(final IBinder who, boolean allowRestart) {
9354        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9355                != PackageManager.PERMISSION_GRANTED) {
9356            throw new SecurityException("Requires permission "
9357                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9358        }
9359
9360        final IBinder.DeathRecipient death = new DeathRecipient() {
9361            @Override
9362            public void binderDied() {
9363                synchronized (this) {
9364                    notifyAll();
9365                }
9366            }
9367        };
9368
9369        try {
9370            who.linkToDeath(death, 0);
9371        } catch (RemoteException e) {
9372            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9373            return;
9374        }
9375
9376        synchronized (this) {
9377            Watchdog.getInstance().setAllowRestart(allowRestart);
9378            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9379            synchronized (death) {
9380                while (who.isBinderAlive()) {
9381                    try {
9382                        death.wait();
9383                    } catch (InterruptedException e) {
9384                    }
9385                }
9386            }
9387            Watchdog.getInstance().setAllowRestart(true);
9388        }
9389    }
9390
9391    @Override
9392    public void restart() {
9393        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9394                != PackageManager.PERMISSION_GRANTED) {
9395            throw new SecurityException("Requires permission "
9396                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9397        }
9398
9399        Log.i(TAG, "Sending shutdown broadcast...");
9400
9401        BroadcastReceiver br = new BroadcastReceiver() {
9402            @Override public void onReceive(Context context, Intent intent) {
9403                // Now the broadcast is done, finish up the low-level shutdown.
9404                Log.i(TAG, "Shutting down activity manager...");
9405                shutdown(10000);
9406                Log.i(TAG, "Shutdown complete, restarting!");
9407                Process.killProcess(Process.myPid());
9408                System.exit(10);
9409            }
9410        };
9411
9412        // First send the high-level shut down broadcast.
9413        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9414        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9415        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9416        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9417        mContext.sendOrderedBroadcastAsUser(intent,
9418                UserHandle.ALL, null, br, mHandler, 0, null, null);
9419        */
9420        br.onReceive(mContext, intent);
9421    }
9422
9423    private long getLowRamTimeSinceIdle(long now) {
9424        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9425    }
9426
9427    @Override
9428    public void performIdleMaintenance() {
9429        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9430                != PackageManager.PERMISSION_GRANTED) {
9431            throw new SecurityException("Requires permission "
9432                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9433        }
9434
9435        synchronized (this) {
9436            final long now = SystemClock.uptimeMillis();
9437            final long timeSinceLastIdle = now - mLastIdleTime;
9438            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9439            mLastIdleTime = now;
9440            mLowRamTimeSinceLastIdle = 0;
9441            if (mLowRamStartTime != 0) {
9442                mLowRamStartTime = now;
9443            }
9444
9445            StringBuilder sb = new StringBuilder(128);
9446            sb.append("Idle maintenance over ");
9447            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9448            sb.append(" low RAM for ");
9449            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9450            Slog.i(TAG, sb.toString());
9451
9452            // If at least 1/3 of our time since the last idle period has been spent
9453            // with RAM low, then we want to kill processes.
9454            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9455
9456            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9457                ProcessRecord proc = mLruProcesses.get(i);
9458                if (proc.notCachedSinceIdle) {
9459                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9460                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9461                        if (doKilling && proc.initialIdlePss != 0
9462                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9463                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9464                                    + " from " + proc.initialIdlePss + ")");
9465                        }
9466                    }
9467                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9468                    proc.notCachedSinceIdle = true;
9469                    proc.initialIdlePss = 0;
9470                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9471                            isSleeping(), now);
9472                }
9473            }
9474
9475            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9476            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9477        }
9478    }
9479
9480    private void retrieveSettings() {
9481        final ContentResolver resolver = mContext.getContentResolver();
9482        String debugApp = Settings.Global.getString(
9483            resolver, Settings.Global.DEBUG_APP);
9484        boolean waitForDebugger = Settings.Global.getInt(
9485            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9486        boolean alwaysFinishActivities = Settings.Global.getInt(
9487            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9488        boolean forceRtl = Settings.Global.getInt(
9489                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9490        // Transfer any global setting for forcing RTL layout, into a System Property
9491        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9492
9493        Configuration configuration = new Configuration();
9494        Settings.System.getConfiguration(resolver, configuration);
9495        if (forceRtl) {
9496            // This will take care of setting the correct layout direction flags
9497            configuration.setLayoutDirection(configuration.locale);
9498        }
9499
9500        synchronized (this) {
9501            mDebugApp = mOrigDebugApp = debugApp;
9502            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9503            mAlwaysFinishActivities = alwaysFinishActivities;
9504            // This happens before any activities are started, so we can
9505            // change mConfiguration in-place.
9506            updateConfigurationLocked(configuration, null, false, true);
9507            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9508        }
9509    }
9510
9511    public boolean testIsSystemReady() {
9512        // no need to synchronize(this) just to read & return the value
9513        return mSystemReady;
9514    }
9515
9516    private static File getCalledPreBootReceiversFile() {
9517        File dataDir = Environment.getDataDirectory();
9518        File systemDir = new File(dataDir, "system");
9519        File fname = new File(systemDir, "called_pre_boots.dat");
9520        return fname;
9521    }
9522
9523    static final int LAST_DONE_VERSION = 10000;
9524
9525    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9526        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9527        File file = getCalledPreBootReceiversFile();
9528        FileInputStream fis = null;
9529        try {
9530            fis = new FileInputStream(file);
9531            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9532            int fvers = dis.readInt();
9533            if (fvers == LAST_DONE_VERSION) {
9534                String vers = dis.readUTF();
9535                String codename = dis.readUTF();
9536                String build = dis.readUTF();
9537                if (android.os.Build.VERSION.RELEASE.equals(vers)
9538                        && android.os.Build.VERSION.CODENAME.equals(codename)
9539                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9540                    int num = dis.readInt();
9541                    while (num > 0) {
9542                        num--;
9543                        String pkg = dis.readUTF();
9544                        String cls = dis.readUTF();
9545                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9546                    }
9547                }
9548            }
9549        } catch (FileNotFoundException e) {
9550        } catch (IOException e) {
9551            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9552        } finally {
9553            if (fis != null) {
9554                try {
9555                    fis.close();
9556                } catch (IOException e) {
9557                }
9558            }
9559        }
9560        return lastDoneReceivers;
9561    }
9562
9563    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9564        File file = getCalledPreBootReceiversFile();
9565        FileOutputStream fos = null;
9566        DataOutputStream dos = null;
9567        try {
9568            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9569            fos = new FileOutputStream(file);
9570            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9571            dos.writeInt(LAST_DONE_VERSION);
9572            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9573            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9574            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9575            dos.writeInt(list.size());
9576            for (int i=0; i<list.size(); i++) {
9577                dos.writeUTF(list.get(i).getPackageName());
9578                dos.writeUTF(list.get(i).getClassName());
9579            }
9580        } catch (IOException e) {
9581            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9582            file.delete();
9583        } finally {
9584            FileUtils.sync(fos);
9585            if (dos != null) {
9586                try {
9587                    dos.close();
9588                } catch (IOException e) {
9589                    // TODO Auto-generated catch block
9590                    e.printStackTrace();
9591                }
9592            }
9593        }
9594    }
9595
9596    public void systemReady(final Runnable goingCallback) {
9597        synchronized(this) {
9598            if (mSystemReady) {
9599                if (goingCallback != null) goingCallback.run();
9600                return;
9601            }
9602
9603            // Check to see if there are any update receivers to run.
9604            if (!mDidUpdate) {
9605                if (mWaitingUpdate) {
9606                    return;
9607                }
9608                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9609                List<ResolveInfo> ris = null;
9610                try {
9611                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9612                            intent, null, 0, 0);
9613                } catch (RemoteException e) {
9614                }
9615                if (ris != null) {
9616                    for (int i=ris.size()-1; i>=0; i--) {
9617                        if ((ris.get(i).activityInfo.applicationInfo.flags
9618                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9619                            ris.remove(i);
9620                        }
9621                    }
9622                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9623
9624                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9625
9626                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9627                    for (int i=0; i<ris.size(); i++) {
9628                        ActivityInfo ai = ris.get(i).activityInfo;
9629                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9630                        if (lastDoneReceivers.contains(comp)) {
9631                            // We already did the pre boot receiver for this app with the current
9632                            // platform version, so don't do it again...
9633                            ris.remove(i);
9634                            i--;
9635                            // ...however, do keep it as one that has been done, so we don't
9636                            // forget about it when rewriting the file of last done receivers.
9637                            doneReceivers.add(comp);
9638                        }
9639                    }
9640
9641                    final int[] users = getUsersLocked();
9642                    for (int i=0; i<ris.size(); i++) {
9643                        ActivityInfo ai = ris.get(i).activityInfo;
9644                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9645                        doneReceivers.add(comp);
9646                        intent.setComponent(comp);
9647                        for (int j=0; j<users.length; j++) {
9648                            IIntentReceiver finisher = null;
9649                            if (i == ris.size()-1 && j == users.length-1) {
9650                                finisher = new IIntentReceiver.Stub() {
9651                                    public void performReceive(Intent intent, int resultCode,
9652                                            String data, Bundle extras, boolean ordered,
9653                                            boolean sticky, int sendingUser) {
9654                                        // The raw IIntentReceiver interface is called
9655                                        // with the AM lock held, so redispatch to
9656                                        // execute our code without the lock.
9657                                        mHandler.post(new Runnable() {
9658                                            public void run() {
9659                                                synchronized (ActivityManagerService.this) {
9660                                                    mDidUpdate = true;
9661                                                }
9662                                                writeLastDonePreBootReceivers(doneReceivers);
9663                                                showBootMessage(mContext.getText(
9664                                                        R.string.android_upgrading_complete),
9665                                                        false);
9666                                                systemReady(goingCallback);
9667                                            }
9668                                        });
9669                                    }
9670                                };
9671                            }
9672                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9673                                    + " for user " + users[j]);
9674                            broadcastIntentLocked(null, null, intent, null, finisher,
9675                                    0, null, null, null, AppOpsManager.OP_NONE,
9676                                    true, false, MY_PID, Process.SYSTEM_UID,
9677                                    users[j]);
9678                            if (finisher != null) {
9679                                mWaitingUpdate = true;
9680                            }
9681                        }
9682                    }
9683                }
9684                if (mWaitingUpdate) {
9685                    return;
9686                }
9687                mDidUpdate = true;
9688            }
9689
9690            mAppOpsService.systemReady();
9691            mUsageStatsService.systemReady();
9692            mSystemReady = true;
9693        }
9694
9695        ArrayList<ProcessRecord> procsToKill = null;
9696        synchronized(mPidsSelfLocked) {
9697            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9698                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9699                if (!isAllowedWhileBooting(proc.info)){
9700                    if (procsToKill == null) {
9701                        procsToKill = new ArrayList<ProcessRecord>();
9702                    }
9703                    procsToKill.add(proc);
9704                }
9705            }
9706        }
9707
9708        synchronized(this) {
9709            if (procsToKill != null) {
9710                for (int i=procsToKill.size()-1; i>=0; i--) {
9711                    ProcessRecord proc = procsToKill.get(i);
9712                    Slog.i(TAG, "Removing system update proc: " + proc);
9713                    removeProcessLocked(proc, true, false, "system update done");
9714                }
9715            }
9716
9717            // Now that we have cleaned up any update processes, we
9718            // are ready to start launching real processes and know that
9719            // we won't trample on them any more.
9720            mProcessesReady = true;
9721        }
9722
9723        Slog.i(TAG, "System now ready");
9724        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9725            SystemClock.uptimeMillis());
9726
9727        synchronized(this) {
9728            // Make sure we have no pre-ready processes sitting around.
9729
9730            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9731                ResolveInfo ri = mContext.getPackageManager()
9732                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9733                                STOCK_PM_FLAGS);
9734                CharSequence errorMsg = null;
9735                if (ri != null) {
9736                    ActivityInfo ai = ri.activityInfo;
9737                    ApplicationInfo app = ai.applicationInfo;
9738                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9739                        mTopAction = Intent.ACTION_FACTORY_TEST;
9740                        mTopData = null;
9741                        mTopComponent = new ComponentName(app.packageName,
9742                                ai.name);
9743                    } else {
9744                        errorMsg = mContext.getResources().getText(
9745                                com.android.internal.R.string.factorytest_not_system);
9746                    }
9747                } else {
9748                    errorMsg = mContext.getResources().getText(
9749                            com.android.internal.R.string.factorytest_no_action);
9750                }
9751                if (errorMsg != null) {
9752                    mTopAction = null;
9753                    mTopData = null;
9754                    mTopComponent = null;
9755                    Message msg = Message.obtain();
9756                    msg.what = SHOW_FACTORY_ERROR_MSG;
9757                    msg.getData().putCharSequence("msg", errorMsg);
9758                    mHandler.sendMessage(msg);
9759                }
9760            }
9761        }
9762
9763        retrieveSettings();
9764
9765        synchronized (this) {
9766            readGrantedUriPermissionsLocked();
9767        }
9768
9769        if (goingCallback != null) goingCallback.run();
9770
9771        mSystemServiceManager.startUser(mCurrentUserId);
9772
9773        synchronized (this) {
9774            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9775                try {
9776                    List apps = AppGlobals.getPackageManager().
9777                        getPersistentApplications(STOCK_PM_FLAGS);
9778                    if (apps != null) {
9779                        int N = apps.size();
9780                        int i;
9781                        for (i=0; i<N; i++) {
9782                            ApplicationInfo info
9783                                = (ApplicationInfo)apps.get(i);
9784                            if (info != null &&
9785                                    !info.packageName.equals("android")) {
9786                                addAppLocked(info, false);
9787                            }
9788                        }
9789                    }
9790                } catch (RemoteException ex) {
9791                    // pm is in same process, this will never happen.
9792                }
9793            }
9794
9795            // Start up initial activity.
9796            mBooting = true;
9797
9798            try {
9799                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9800                    Message msg = Message.obtain();
9801                    msg.what = SHOW_UID_ERROR_MSG;
9802                    mHandler.sendMessage(msg);
9803                }
9804            } catch (RemoteException e) {
9805            }
9806
9807            long ident = Binder.clearCallingIdentity();
9808            try {
9809                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9810                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9811                        | Intent.FLAG_RECEIVER_FOREGROUND);
9812                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9813                broadcastIntentLocked(null, null, intent,
9814                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9815                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9816                intent = new Intent(Intent.ACTION_USER_STARTING);
9817                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9818                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9819                broadcastIntentLocked(null, null, intent,
9820                        null, new IIntentReceiver.Stub() {
9821                            @Override
9822                            public void performReceive(Intent intent, int resultCode, String data,
9823                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9824                                    throws RemoteException {
9825                            }
9826                        }, 0, null, null,
9827                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9828                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9829            } catch (Throwable t) {
9830                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9831            } finally {
9832                Binder.restoreCallingIdentity(ident);
9833            }
9834            mStackSupervisor.resumeTopActivitiesLocked();
9835            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9836        }
9837    }
9838
9839    private boolean makeAppCrashingLocked(ProcessRecord app,
9840            String shortMsg, String longMsg, String stackTrace) {
9841        app.crashing = true;
9842        app.crashingReport = generateProcessError(app,
9843                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9844        startAppProblemLocked(app);
9845        app.stopFreezingAllLocked();
9846        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9847    }
9848
9849    private void makeAppNotRespondingLocked(ProcessRecord app,
9850            String activity, String shortMsg, String longMsg) {
9851        app.notResponding = true;
9852        app.notRespondingReport = generateProcessError(app,
9853                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9854                activity, shortMsg, longMsg, null);
9855        startAppProblemLocked(app);
9856        app.stopFreezingAllLocked();
9857    }
9858
9859    /**
9860     * Generate a process error record, suitable for attachment to a ProcessRecord.
9861     *
9862     * @param app The ProcessRecord in which the error occurred.
9863     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9864     *                      ActivityManager.AppErrorStateInfo
9865     * @param activity The activity associated with the crash, if known.
9866     * @param shortMsg Short message describing the crash.
9867     * @param longMsg Long message describing the crash.
9868     * @param stackTrace Full crash stack trace, may be null.
9869     *
9870     * @return Returns a fully-formed AppErrorStateInfo record.
9871     */
9872    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9873            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9874        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9875
9876        report.condition = condition;
9877        report.processName = app.processName;
9878        report.pid = app.pid;
9879        report.uid = app.info.uid;
9880        report.tag = activity;
9881        report.shortMsg = shortMsg;
9882        report.longMsg = longMsg;
9883        report.stackTrace = stackTrace;
9884
9885        return report;
9886    }
9887
9888    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9889        synchronized (this) {
9890            app.crashing = false;
9891            app.crashingReport = null;
9892            app.notResponding = false;
9893            app.notRespondingReport = null;
9894            if (app.anrDialog == fromDialog) {
9895                app.anrDialog = null;
9896            }
9897            if (app.waitDialog == fromDialog) {
9898                app.waitDialog = null;
9899            }
9900            if (app.pid > 0 && app.pid != MY_PID) {
9901                handleAppCrashLocked(app, null, null, null);
9902                killUnneededProcessLocked(app, "user request after error");
9903            }
9904        }
9905    }
9906
9907    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9908            String stackTrace) {
9909        long now = SystemClock.uptimeMillis();
9910
9911        Long crashTime;
9912        if (!app.isolated) {
9913            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9914        } else {
9915            crashTime = null;
9916        }
9917        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9918            // This process loses!
9919            Slog.w(TAG, "Process " + app.info.processName
9920                    + " has crashed too many times: killing!");
9921            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9922                    app.userId, app.info.processName, app.uid);
9923            mStackSupervisor.handleAppCrashLocked(app);
9924            if (!app.persistent) {
9925                // We don't want to start this process again until the user
9926                // explicitly does so...  but for persistent process, we really
9927                // need to keep it running.  If a persistent process is actually
9928                // repeatedly crashing, then badness for everyone.
9929                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9930                        app.info.processName);
9931                if (!app.isolated) {
9932                    // XXX We don't have a way to mark isolated processes
9933                    // as bad, since they don't have a peristent identity.
9934                    mBadProcesses.put(app.info.processName, app.uid,
9935                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9936                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9937                }
9938                app.bad = true;
9939                app.removed = true;
9940                // Don't let services in this process be restarted and potentially
9941                // annoy the user repeatedly.  Unless it is persistent, since those
9942                // processes run critical code.
9943                removeProcessLocked(app, false, false, "crash");
9944                mStackSupervisor.resumeTopActivitiesLocked();
9945                return false;
9946            }
9947            mStackSupervisor.resumeTopActivitiesLocked();
9948        } else {
9949            mStackSupervisor.finishTopRunningActivityLocked(app);
9950        }
9951
9952        // Bump up the crash count of any services currently running in the proc.
9953        for (int i=app.services.size()-1; i>=0; i--) {
9954            // Any services running in the application need to be placed
9955            // back in the pending list.
9956            ServiceRecord sr = app.services.valueAt(i);
9957            sr.crashCount++;
9958        }
9959
9960        // If the crashing process is what we consider to be the "home process" and it has been
9961        // replaced by a third-party app, clear the package preferred activities from packages
9962        // with a home activity running in the process to prevent a repeatedly crashing app
9963        // from blocking the user to manually clear the list.
9964        final ArrayList<ActivityRecord> activities = app.activities;
9965        if (app == mHomeProcess && activities.size() > 0
9966                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9967            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9968                final ActivityRecord r = activities.get(activityNdx);
9969                if (r.isHomeActivity()) {
9970                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9971                    try {
9972                        ActivityThread.getPackageManager()
9973                                .clearPackagePreferredActivities(r.packageName);
9974                    } catch (RemoteException c) {
9975                        // pm is in same process, this will never happen.
9976                    }
9977                }
9978            }
9979        }
9980
9981        if (!app.isolated) {
9982            // XXX Can't keep track of crash times for isolated processes,
9983            // because they don't have a perisistent identity.
9984            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9985        }
9986
9987        return true;
9988    }
9989
9990    void startAppProblemLocked(ProcessRecord app) {
9991        if (app.userId == mCurrentUserId) {
9992            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9993                    mContext, app.info.packageName, app.info.flags);
9994        } else {
9995            // If this app is not running under the current user, then we
9996            // can't give it a report button because that would require
9997            // launching the report UI under a different user.
9998            app.errorReportReceiver = null;
9999        }
10000        skipCurrentReceiverLocked(app);
10001    }
10002
10003    void skipCurrentReceiverLocked(ProcessRecord app) {
10004        for (BroadcastQueue queue : mBroadcastQueues) {
10005            queue.skipCurrentReceiverLocked(app);
10006        }
10007    }
10008
10009    /**
10010     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10011     * The application process will exit immediately after this call returns.
10012     * @param app object of the crashing app, null for the system server
10013     * @param crashInfo describing the exception
10014     */
10015    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10016        ProcessRecord r = findAppProcess(app, "Crash");
10017        final String processName = app == null ? "system_server"
10018                : (r == null ? "unknown" : r.processName);
10019
10020        handleApplicationCrashInner("crash", r, processName, crashInfo);
10021    }
10022
10023    /* Native crash reporting uses this inner version because it needs to be somewhat
10024     * decoupled from the AM-managed cleanup lifecycle
10025     */
10026    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10027            ApplicationErrorReport.CrashInfo crashInfo) {
10028        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10029                UserHandle.getUserId(Binder.getCallingUid()), processName,
10030                r == null ? -1 : r.info.flags,
10031                crashInfo.exceptionClassName,
10032                crashInfo.exceptionMessage,
10033                crashInfo.throwFileName,
10034                crashInfo.throwLineNumber);
10035
10036        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10037
10038        crashApplication(r, crashInfo);
10039    }
10040
10041    public void handleApplicationStrictModeViolation(
10042            IBinder app,
10043            int violationMask,
10044            StrictMode.ViolationInfo info) {
10045        ProcessRecord r = findAppProcess(app, "StrictMode");
10046        if (r == null) {
10047            return;
10048        }
10049
10050        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10051            Integer stackFingerprint = info.hashCode();
10052            boolean logIt = true;
10053            synchronized (mAlreadyLoggedViolatedStacks) {
10054                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10055                    logIt = false;
10056                    // TODO: sub-sample into EventLog for these, with
10057                    // the info.durationMillis?  Then we'd get
10058                    // the relative pain numbers, without logging all
10059                    // the stack traces repeatedly.  We'd want to do
10060                    // likewise in the client code, which also does
10061                    // dup suppression, before the Binder call.
10062                } else {
10063                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10064                        mAlreadyLoggedViolatedStacks.clear();
10065                    }
10066                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10067                }
10068            }
10069            if (logIt) {
10070                logStrictModeViolationToDropBox(r, info);
10071            }
10072        }
10073
10074        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10075            AppErrorResult result = new AppErrorResult();
10076            synchronized (this) {
10077                final long origId = Binder.clearCallingIdentity();
10078
10079                Message msg = Message.obtain();
10080                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10081                HashMap<String, Object> data = new HashMap<String, Object>();
10082                data.put("result", result);
10083                data.put("app", r);
10084                data.put("violationMask", violationMask);
10085                data.put("info", info);
10086                msg.obj = data;
10087                mHandler.sendMessage(msg);
10088
10089                Binder.restoreCallingIdentity(origId);
10090            }
10091            int res = result.get();
10092            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10093        }
10094    }
10095
10096    // Depending on the policy in effect, there could be a bunch of
10097    // these in quick succession so we try to batch these together to
10098    // minimize disk writes, number of dropbox entries, and maximize
10099    // compression, by having more fewer, larger records.
10100    private void logStrictModeViolationToDropBox(
10101            ProcessRecord process,
10102            StrictMode.ViolationInfo info) {
10103        if (info == null) {
10104            return;
10105        }
10106        final boolean isSystemApp = process == null ||
10107                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10108                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10109        final String processName = process == null ? "unknown" : process.processName;
10110        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10111        final DropBoxManager dbox = (DropBoxManager)
10112                mContext.getSystemService(Context.DROPBOX_SERVICE);
10113
10114        // Exit early if the dropbox isn't configured to accept this report type.
10115        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10116
10117        boolean bufferWasEmpty;
10118        boolean needsFlush;
10119        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10120        synchronized (sb) {
10121            bufferWasEmpty = sb.length() == 0;
10122            appendDropBoxProcessHeaders(process, processName, sb);
10123            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10124            sb.append("System-App: ").append(isSystemApp).append("\n");
10125            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10126            if (info.violationNumThisLoop != 0) {
10127                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10128            }
10129            if (info.numAnimationsRunning != 0) {
10130                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10131            }
10132            if (info.broadcastIntentAction != null) {
10133                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10134            }
10135            if (info.durationMillis != -1) {
10136                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10137            }
10138            if (info.numInstances != -1) {
10139                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10140            }
10141            if (info.tags != null) {
10142                for (String tag : info.tags) {
10143                    sb.append("Span-Tag: ").append(tag).append("\n");
10144                }
10145            }
10146            sb.append("\n");
10147            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10148                sb.append(info.crashInfo.stackTrace);
10149            }
10150            sb.append("\n");
10151
10152            // Only buffer up to ~64k.  Various logging bits truncate
10153            // things at 128k.
10154            needsFlush = (sb.length() > 64 * 1024);
10155        }
10156
10157        // Flush immediately if the buffer's grown too large, or this
10158        // is a non-system app.  Non-system apps are isolated with a
10159        // different tag & policy and not batched.
10160        //
10161        // Batching is useful during internal testing with
10162        // StrictMode settings turned up high.  Without batching,
10163        // thousands of separate files could be created on boot.
10164        if (!isSystemApp || needsFlush) {
10165            new Thread("Error dump: " + dropboxTag) {
10166                @Override
10167                public void run() {
10168                    String report;
10169                    synchronized (sb) {
10170                        report = sb.toString();
10171                        sb.delete(0, sb.length());
10172                        sb.trimToSize();
10173                    }
10174                    if (report.length() != 0) {
10175                        dbox.addText(dropboxTag, report);
10176                    }
10177                }
10178            }.start();
10179            return;
10180        }
10181
10182        // System app batching:
10183        if (!bufferWasEmpty) {
10184            // An existing dropbox-writing thread is outstanding, so
10185            // we don't need to start it up.  The existing thread will
10186            // catch the buffer appends we just did.
10187            return;
10188        }
10189
10190        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10191        // (After this point, we shouldn't access AMS internal data structures.)
10192        new Thread("Error dump: " + dropboxTag) {
10193            @Override
10194            public void run() {
10195                // 5 second sleep to let stacks arrive and be batched together
10196                try {
10197                    Thread.sleep(5000);  // 5 seconds
10198                } catch (InterruptedException e) {}
10199
10200                String errorReport;
10201                synchronized (mStrictModeBuffer) {
10202                    errorReport = mStrictModeBuffer.toString();
10203                    if (errorReport.length() == 0) {
10204                        return;
10205                    }
10206                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10207                    mStrictModeBuffer.trimToSize();
10208                }
10209                dbox.addText(dropboxTag, errorReport);
10210            }
10211        }.start();
10212    }
10213
10214    /**
10215     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10216     * @param app object of the crashing app, null for the system server
10217     * @param tag reported by the caller
10218     * @param crashInfo describing the context of the error
10219     * @return true if the process should exit immediately (WTF is fatal)
10220     */
10221    public boolean handleApplicationWtf(IBinder app, String tag,
10222            ApplicationErrorReport.CrashInfo crashInfo) {
10223        ProcessRecord r = findAppProcess(app, "WTF");
10224        final String processName = app == null ? "system_server"
10225                : (r == null ? "unknown" : r.processName);
10226
10227        EventLog.writeEvent(EventLogTags.AM_WTF,
10228                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10229                processName,
10230                r == null ? -1 : r.info.flags,
10231                tag, crashInfo.exceptionMessage);
10232
10233        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10234
10235        if (r != null && r.pid != Process.myPid() &&
10236                Settings.Global.getInt(mContext.getContentResolver(),
10237                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10238            crashApplication(r, crashInfo);
10239            return true;
10240        } else {
10241            return false;
10242        }
10243    }
10244
10245    /**
10246     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10247     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10248     */
10249    private ProcessRecord findAppProcess(IBinder app, String reason) {
10250        if (app == null) {
10251            return null;
10252        }
10253
10254        synchronized (this) {
10255            final int NP = mProcessNames.getMap().size();
10256            for (int ip=0; ip<NP; ip++) {
10257                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10258                final int NA = apps.size();
10259                for (int ia=0; ia<NA; ia++) {
10260                    ProcessRecord p = apps.valueAt(ia);
10261                    if (p.thread != null && p.thread.asBinder() == app) {
10262                        return p;
10263                    }
10264                }
10265            }
10266
10267            Slog.w(TAG, "Can't find mystery application for " + reason
10268                    + " from pid=" + Binder.getCallingPid()
10269                    + " uid=" + Binder.getCallingUid() + ": " + app);
10270            return null;
10271        }
10272    }
10273
10274    /**
10275     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10276     * to append various headers to the dropbox log text.
10277     */
10278    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10279            StringBuilder sb) {
10280        // Watchdog thread ends up invoking this function (with
10281        // a null ProcessRecord) to add the stack file to dropbox.
10282        // Do not acquire a lock on this (am) in such cases, as it
10283        // could cause a potential deadlock, if and when watchdog
10284        // is invoked due to unavailability of lock on am and it
10285        // would prevent watchdog from killing system_server.
10286        if (process == null) {
10287            sb.append("Process: ").append(processName).append("\n");
10288            return;
10289        }
10290        // Note: ProcessRecord 'process' is guarded by the service
10291        // instance.  (notably process.pkgList, which could otherwise change
10292        // concurrently during execution of this method)
10293        synchronized (this) {
10294            sb.append("Process: ").append(processName).append("\n");
10295            int flags = process.info.flags;
10296            IPackageManager pm = AppGlobals.getPackageManager();
10297            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10298            for (int ip=0; ip<process.pkgList.size(); ip++) {
10299                String pkg = process.pkgList.keyAt(ip);
10300                sb.append("Package: ").append(pkg);
10301                try {
10302                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10303                    if (pi != null) {
10304                        sb.append(" v").append(pi.versionCode);
10305                        if (pi.versionName != null) {
10306                            sb.append(" (").append(pi.versionName).append(")");
10307                        }
10308                    }
10309                } catch (RemoteException e) {
10310                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10311                }
10312                sb.append("\n");
10313            }
10314        }
10315    }
10316
10317    private static String processClass(ProcessRecord process) {
10318        if (process == null || process.pid == MY_PID) {
10319            return "system_server";
10320        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10321            return "system_app";
10322        } else {
10323            return "data_app";
10324        }
10325    }
10326
10327    /**
10328     * Write a description of an error (crash, WTF, ANR) to the drop box.
10329     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10330     * @param process which caused the error, null means the system server
10331     * @param activity which triggered the error, null if unknown
10332     * @param parent activity related to the error, null if unknown
10333     * @param subject line related to the error, null if absent
10334     * @param report in long form describing the error, null if absent
10335     * @param logFile to include in the report, null if none
10336     * @param crashInfo giving an application stack trace, null if absent
10337     */
10338    public void addErrorToDropBox(String eventType,
10339            ProcessRecord process, String processName, ActivityRecord activity,
10340            ActivityRecord parent, String subject,
10341            final String report, final File logFile,
10342            final ApplicationErrorReport.CrashInfo crashInfo) {
10343        // NOTE -- this must never acquire the ActivityManagerService lock,
10344        // otherwise the watchdog may be prevented from resetting the system.
10345
10346        final String dropboxTag = processClass(process) + "_" + eventType;
10347        final DropBoxManager dbox = (DropBoxManager)
10348                mContext.getSystemService(Context.DROPBOX_SERVICE);
10349
10350        // Exit early if the dropbox isn't configured to accept this report type.
10351        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10352
10353        final StringBuilder sb = new StringBuilder(1024);
10354        appendDropBoxProcessHeaders(process, processName, sb);
10355        if (activity != null) {
10356            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10357        }
10358        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10359            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10360        }
10361        if (parent != null && parent != activity) {
10362            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10363        }
10364        if (subject != null) {
10365            sb.append("Subject: ").append(subject).append("\n");
10366        }
10367        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10368        if (Debug.isDebuggerConnected()) {
10369            sb.append("Debugger: Connected\n");
10370        }
10371        sb.append("\n");
10372
10373        // Do the rest in a worker thread to avoid blocking the caller on I/O
10374        // (After this point, we shouldn't access AMS internal data structures.)
10375        Thread worker = new Thread("Error dump: " + dropboxTag) {
10376            @Override
10377            public void run() {
10378                if (report != null) {
10379                    sb.append(report);
10380                }
10381                if (logFile != null) {
10382                    try {
10383                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10384                                    "\n\n[[TRUNCATED]]"));
10385                    } catch (IOException e) {
10386                        Slog.e(TAG, "Error reading " + logFile, e);
10387                    }
10388                }
10389                if (crashInfo != null && crashInfo.stackTrace != null) {
10390                    sb.append(crashInfo.stackTrace);
10391                }
10392
10393                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10394                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10395                if (lines > 0) {
10396                    sb.append("\n");
10397
10398                    // Merge several logcat streams, and take the last N lines
10399                    InputStreamReader input = null;
10400                    try {
10401                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10402                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10403                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10404
10405                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10406                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10407                        input = new InputStreamReader(logcat.getInputStream());
10408
10409                        int num;
10410                        char[] buf = new char[8192];
10411                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10412                    } catch (IOException e) {
10413                        Slog.e(TAG, "Error running logcat", e);
10414                    } finally {
10415                        if (input != null) try { input.close(); } catch (IOException e) {}
10416                    }
10417                }
10418
10419                dbox.addText(dropboxTag, sb.toString());
10420            }
10421        };
10422
10423        if (process == null) {
10424            // If process is null, we are being called from some internal code
10425            // and may be about to die -- run this synchronously.
10426            worker.run();
10427        } else {
10428            worker.start();
10429        }
10430    }
10431
10432    /**
10433     * Bring up the "unexpected error" dialog box for a crashing app.
10434     * Deal with edge cases (intercepts from instrumented applications,
10435     * ActivityController, error intent receivers, that sort of thing).
10436     * @param r the application crashing
10437     * @param crashInfo describing the failure
10438     */
10439    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10440        long timeMillis = System.currentTimeMillis();
10441        String shortMsg = crashInfo.exceptionClassName;
10442        String longMsg = crashInfo.exceptionMessage;
10443        String stackTrace = crashInfo.stackTrace;
10444        if (shortMsg != null && longMsg != null) {
10445            longMsg = shortMsg + ": " + longMsg;
10446        } else if (shortMsg != null) {
10447            longMsg = shortMsg;
10448        }
10449
10450        AppErrorResult result = new AppErrorResult();
10451        synchronized (this) {
10452            if (mController != null) {
10453                try {
10454                    String name = r != null ? r.processName : null;
10455                    int pid = r != null ? r.pid : Binder.getCallingPid();
10456                    if (!mController.appCrashed(name, pid,
10457                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10458                        Slog.w(TAG, "Force-killing crashed app " + name
10459                                + " at watcher's request");
10460                        Process.killProcess(pid);
10461                        return;
10462                    }
10463                } catch (RemoteException e) {
10464                    mController = null;
10465                    Watchdog.getInstance().setActivityController(null);
10466                }
10467            }
10468
10469            final long origId = Binder.clearCallingIdentity();
10470
10471            // If this process is running instrumentation, finish it.
10472            if (r != null && r.instrumentationClass != null) {
10473                Slog.w(TAG, "Error in app " + r.processName
10474                      + " running instrumentation " + r.instrumentationClass + ":");
10475                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10476                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10477                Bundle info = new Bundle();
10478                info.putString("shortMsg", shortMsg);
10479                info.putString("longMsg", longMsg);
10480                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10481                Binder.restoreCallingIdentity(origId);
10482                return;
10483            }
10484
10485            // If we can't identify the process or it's already exceeded its crash quota,
10486            // quit right away without showing a crash dialog.
10487            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10488                Binder.restoreCallingIdentity(origId);
10489                return;
10490            }
10491
10492            Message msg = Message.obtain();
10493            msg.what = SHOW_ERROR_MSG;
10494            HashMap data = new HashMap();
10495            data.put("result", result);
10496            data.put("app", r);
10497            msg.obj = data;
10498            mHandler.sendMessage(msg);
10499
10500            Binder.restoreCallingIdentity(origId);
10501        }
10502
10503        int res = result.get();
10504
10505        Intent appErrorIntent = null;
10506        synchronized (this) {
10507            if (r != null && !r.isolated) {
10508                // XXX Can't keep track of crash time for isolated processes,
10509                // since they don't have a persistent identity.
10510                mProcessCrashTimes.put(r.info.processName, r.uid,
10511                        SystemClock.uptimeMillis());
10512            }
10513            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10514                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10515            }
10516        }
10517
10518        if (appErrorIntent != null) {
10519            try {
10520                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10521            } catch (ActivityNotFoundException e) {
10522                Slog.w(TAG, "bug report receiver dissappeared", e);
10523            }
10524        }
10525    }
10526
10527    Intent createAppErrorIntentLocked(ProcessRecord r,
10528            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10529        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10530        if (report == null) {
10531            return null;
10532        }
10533        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10534        result.setComponent(r.errorReportReceiver);
10535        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10536        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10537        return result;
10538    }
10539
10540    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10541            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10542        if (r.errorReportReceiver == null) {
10543            return null;
10544        }
10545
10546        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10547            return null;
10548        }
10549
10550        ApplicationErrorReport report = new ApplicationErrorReport();
10551        report.packageName = r.info.packageName;
10552        report.installerPackageName = r.errorReportReceiver.getPackageName();
10553        report.processName = r.processName;
10554        report.time = timeMillis;
10555        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10556
10557        if (r.crashing || r.forceCrashReport) {
10558            report.type = ApplicationErrorReport.TYPE_CRASH;
10559            report.crashInfo = crashInfo;
10560        } else if (r.notResponding) {
10561            report.type = ApplicationErrorReport.TYPE_ANR;
10562            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10563
10564            report.anrInfo.activity = r.notRespondingReport.tag;
10565            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10566            report.anrInfo.info = r.notRespondingReport.longMsg;
10567        }
10568
10569        return report;
10570    }
10571
10572    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10573        enforceNotIsolatedCaller("getProcessesInErrorState");
10574        // assume our apps are happy - lazy create the list
10575        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10576
10577        final boolean allUsers = ActivityManager.checkUidPermission(
10578                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10579                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10580        int userId = UserHandle.getUserId(Binder.getCallingUid());
10581
10582        synchronized (this) {
10583
10584            // iterate across all processes
10585            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10586                ProcessRecord app = mLruProcesses.get(i);
10587                if (!allUsers && app.userId != userId) {
10588                    continue;
10589                }
10590                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10591                    // This one's in trouble, so we'll generate a report for it
10592                    // crashes are higher priority (in case there's a crash *and* an anr)
10593                    ActivityManager.ProcessErrorStateInfo report = null;
10594                    if (app.crashing) {
10595                        report = app.crashingReport;
10596                    } else if (app.notResponding) {
10597                        report = app.notRespondingReport;
10598                    }
10599
10600                    if (report != null) {
10601                        if (errList == null) {
10602                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10603                        }
10604                        errList.add(report);
10605                    } else {
10606                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10607                                " crashing = " + app.crashing +
10608                                " notResponding = " + app.notResponding);
10609                    }
10610                }
10611            }
10612        }
10613
10614        return errList;
10615    }
10616
10617    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10618        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10619            if (currApp != null) {
10620                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10621            }
10622            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10623        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10624            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10625        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10626            if (currApp != null) {
10627                currApp.lru = 0;
10628            }
10629            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10630        } else if (adj >= ProcessList.SERVICE_ADJ) {
10631            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10632        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10633            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10634        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10635            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10636        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10637            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10638        } else {
10639            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10640        }
10641    }
10642
10643    private void fillInProcMemInfo(ProcessRecord app,
10644            ActivityManager.RunningAppProcessInfo outInfo) {
10645        outInfo.pid = app.pid;
10646        outInfo.uid = app.info.uid;
10647        if (mHeavyWeightProcess == app) {
10648            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10649        }
10650        if (app.persistent) {
10651            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10652        }
10653        if (app.activities.size() > 0) {
10654            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10655        }
10656        outInfo.lastTrimLevel = app.trimMemoryLevel;
10657        int adj = app.curAdj;
10658        outInfo.importance = oomAdjToImportance(adj, outInfo);
10659        outInfo.importanceReasonCode = app.adjTypeCode;
10660        outInfo.processState = app.curProcState;
10661    }
10662
10663    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10664        enforceNotIsolatedCaller("getRunningAppProcesses");
10665        // Lazy instantiation of list
10666        List<ActivityManager.RunningAppProcessInfo> runList = null;
10667        final boolean allUsers = ActivityManager.checkUidPermission(
10668                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10669                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10670        int userId = UserHandle.getUserId(Binder.getCallingUid());
10671        synchronized (this) {
10672            // Iterate across all processes
10673            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10674                ProcessRecord app = mLruProcesses.get(i);
10675                if (!allUsers && app.userId != userId) {
10676                    continue;
10677                }
10678                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10679                    // Generate process state info for running application
10680                    ActivityManager.RunningAppProcessInfo currApp =
10681                        new ActivityManager.RunningAppProcessInfo(app.processName,
10682                                app.pid, app.getPackageList());
10683                    fillInProcMemInfo(app, currApp);
10684                    if (app.adjSource instanceof ProcessRecord) {
10685                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10686                        currApp.importanceReasonImportance = oomAdjToImportance(
10687                                app.adjSourceOom, null);
10688                    } else if (app.adjSource instanceof ActivityRecord) {
10689                        ActivityRecord r = (ActivityRecord)app.adjSource;
10690                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10691                    }
10692                    if (app.adjTarget instanceof ComponentName) {
10693                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10694                    }
10695                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10696                    //        + " lru=" + currApp.lru);
10697                    if (runList == null) {
10698                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10699                    }
10700                    runList.add(currApp);
10701                }
10702            }
10703        }
10704        return runList;
10705    }
10706
10707    public List<ApplicationInfo> getRunningExternalApplications() {
10708        enforceNotIsolatedCaller("getRunningExternalApplications");
10709        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10710        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10711        if (runningApps != null && runningApps.size() > 0) {
10712            Set<String> extList = new HashSet<String>();
10713            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10714                if (app.pkgList != null) {
10715                    for (String pkg : app.pkgList) {
10716                        extList.add(pkg);
10717                    }
10718                }
10719            }
10720            IPackageManager pm = AppGlobals.getPackageManager();
10721            for (String pkg : extList) {
10722                try {
10723                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10724                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10725                        retList.add(info);
10726                    }
10727                } catch (RemoteException e) {
10728                }
10729            }
10730        }
10731        return retList;
10732    }
10733
10734    @Override
10735    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10736        enforceNotIsolatedCaller("getMyMemoryState");
10737        synchronized (this) {
10738            ProcessRecord proc;
10739            synchronized (mPidsSelfLocked) {
10740                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10741            }
10742            fillInProcMemInfo(proc, outInfo);
10743        }
10744    }
10745
10746    @Override
10747    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10748        if (checkCallingPermission(android.Manifest.permission.DUMP)
10749                != PackageManager.PERMISSION_GRANTED) {
10750            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10751                    + Binder.getCallingPid()
10752                    + ", uid=" + Binder.getCallingUid()
10753                    + " without permission "
10754                    + android.Manifest.permission.DUMP);
10755            return;
10756        }
10757
10758        boolean dumpAll = false;
10759        boolean dumpClient = false;
10760        String dumpPackage = null;
10761
10762        int opti = 0;
10763        while (opti < args.length) {
10764            String opt = args[opti];
10765            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10766                break;
10767            }
10768            opti++;
10769            if ("-a".equals(opt)) {
10770                dumpAll = true;
10771            } else if ("-c".equals(opt)) {
10772                dumpClient = true;
10773            } else if ("-h".equals(opt)) {
10774                pw.println("Activity manager dump options:");
10775                pw.println("  [-a] [-c] [-h] [cmd] ...");
10776                pw.println("  cmd may be one of:");
10777                pw.println("    a[ctivities]: activity stack state");
10778                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10779                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10780                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10781                pw.println("    o[om]: out of memory management");
10782                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10783                pw.println("    provider [COMP_SPEC]: provider client-side state");
10784                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10785                pw.println("    service [COMP_SPEC]: service client-side state");
10786                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10787                pw.println("    all: dump all activities");
10788                pw.println("    top: dump the top activity");
10789                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10790                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10791                pw.println("    a partial substring in a component name, a");
10792                pw.println("    hex object identifier.");
10793                pw.println("  -a: include all available server state.");
10794                pw.println("  -c: include client state.");
10795                return;
10796            } else {
10797                pw.println("Unknown argument: " + opt + "; use -h for help");
10798            }
10799        }
10800
10801        long origId = Binder.clearCallingIdentity();
10802        boolean more = false;
10803        // Is the caller requesting to dump a particular piece of data?
10804        if (opti < args.length) {
10805            String cmd = args[opti];
10806            opti++;
10807            if ("activities".equals(cmd) || "a".equals(cmd)) {
10808                synchronized (this) {
10809                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10810                }
10811            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10812                String[] newArgs;
10813                String name;
10814                if (opti >= args.length) {
10815                    name = null;
10816                    newArgs = EMPTY_STRING_ARRAY;
10817                } else {
10818                    name = args[opti];
10819                    opti++;
10820                    newArgs = new String[args.length - opti];
10821                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10822                            args.length - opti);
10823                }
10824                synchronized (this) {
10825                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10826                }
10827            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10828                String[] newArgs;
10829                String name;
10830                if (opti >= args.length) {
10831                    name = null;
10832                    newArgs = EMPTY_STRING_ARRAY;
10833                } else {
10834                    name = args[opti];
10835                    opti++;
10836                    newArgs = new String[args.length - opti];
10837                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10838                            args.length - opti);
10839                }
10840                synchronized (this) {
10841                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10842                }
10843            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10844                String[] newArgs;
10845                String name;
10846                if (opti >= args.length) {
10847                    name = null;
10848                    newArgs = EMPTY_STRING_ARRAY;
10849                } else {
10850                    name = args[opti];
10851                    opti++;
10852                    newArgs = new String[args.length - opti];
10853                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10854                            args.length - opti);
10855                }
10856                synchronized (this) {
10857                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10858                }
10859            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10860                synchronized (this) {
10861                    dumpOomLocked(fd, pw, args, opti, true);
10862                }
10863            } else if ("provider".equals(cmd)) {
10864                String[] newArgs;
10865                String name;
10866                if (opti >= args.length) {
10867                    name = null;
10868                    newArgs = EMPTY_STRING_ARRAY;
10869                } else {
10870                    name = args[opti];
10871                    opti++;
10872                    newArgs = new String[args.length - opti];
10873                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10874                }
10875                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10876                    pw.println("No providers match: " + name);
10877                    pw.println("Use -h for help.");
10878                }
10879            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10880                synchronized (this) {
10881                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10882                }
10883            } else if ("service".equals(cmd)) {
10884                String[] newArgs;
10885                String name;
10886                if (opti >= args.length) {
10887                    name = null;
10888                    newArgs = EMPTY_STRING_ARRAY;
10889                } else {
10890                    name = args[opti];
10891                    opti++;
10892                    newArgs = new String[args.length - opti];
10893                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10894                            args.length - opti);
10895                }
10896                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10897                    pw.println("No services match: " + name);
10898                    pw.println("Use -h for help.");
10899                }
10900            } else if ("package".equals(cmd)) {
10901                String[] newArgs;
10902                if (opti >= args.length) {
10903                    pw.println("package: no package name specified");
10904                    pw.println("Use -h for help.");
10905                } else {
10906                    dumpPackage = args[opti];
10907                    opti++;
10908                    newArgs = new String[args.length - opti];
10909                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10910                            args.length - opti);
10911                    args = newArgs;
10912                    opti = 0;
10913                    more = true;
10914                }
10915            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10916                synchronized (this) {
10917                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10918                }
10919            } else {
10920                // Dumping a single activity?
10921                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10922                    pw.println("Bad activity command, or no activities match: " + cmd);
10923                    pw.println("Use -h for help.");
10924                }
10925            }
10926            if (!more) {
10927                Binder.restoreCallingIdentity(origId);
10928                return;
10929            }
10930        }
10931
10932        // No piece of data specified, dump everything.
10933        synchronized (this) {
10934            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10935            pw.println();
10936            if (dumpAll) {
10937                pw.println("-------------------------------------------------------------------------------");
10938            }
10939            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10940            pw.println();
10941            if (dumpAll) {
10942                pw.println("-------------------------------------------------------------------------------");
10943            }
10944            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10945            pw.println();
10946            if (dumpAll) {
10947                pw.println("-------------------------------------------------------------------------------");
10948            }
10949            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10950            pw.println();
10951            if (dumpAll) {
10952                pw.println("-------------------------------------------------------------------------------");
10953            }
10954            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10955            pw.println();
10956            if (dumpAll) {
10957                pw.println("-------------------------------------------------------------------------------");
10958            }
10959            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10960        }
10961        Binder.restoreCallingIdentity(origId);
10962    }
10963
10964    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10965            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10966        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10967
10968        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10969                dumpPackage);
10970        boolean needSep = printedAnything;
10971
10972        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10973                dumpPackage, needSep, "  mFocusedActivity: ");
10974        if (printed) {
10975            printedAnything = true;
10976            needSep = false;
10977        }
10978
10979        if (dumpPackage == null) {
10980            if (needSep) {
10981                pw.println();
10982            }
10983            needSep = true;
10984            printedAnything = true;
10985            mStackSupervisor.dump(pw, "  ");
10986        }
10987
10988        if (mRecentTasks.size() > 0) {
10989            boolean printedHeader = false;
10990
10991            final int N = mRecentTasks.size();
10992            for (int i=0; i<N; i++) {
10993                TaskRecord tr = mRecentTasks.get(i);
10994                if (dumpPackage != null) {
10995                    if (tr.realActivity == null ||
10996                            !dumpPackage.equals(tr.realActivity)) {
10997                        continue;
10998                    }
10999                }
11000                if (!printedHeader) {
11001                    if (needSep) {
11002                        pw.println();
11003                    }
11004                    pw.println("  Recent tasks:");
11005                    printedHeader = true;
11006                    printedAnything = true;
11007                }
11008                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11009                        pw.println(tr);
11010                if (dumpAll) {
11011                    mRecentTasks.get(i).dump(pw, "    ");
11012                }
11013            }
11014        }
11015
11016        if (!printedAnything) {
11017            pw.println("  (nothing)");
11018        }
11019    }
11020
11021    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11022            int opti, boolean dumpAll, String dumpPackage) {
11023        boolean needSep = false;
11024        boolean printedAnything = false;
11025        int numPers = 0;
11026
11027        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11028
11029        if (dumpAll) {
11030            final int NP = mProcessNames.getMap().size();
11031            for (int ip=0; ip<NP; ip++) {
11032                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11033                final int NA = procs.size();
11034                for (int ia=0; ia<NA; ia++) {
11035                    ProcessRecord r = procs.valueAt(ia);
11036                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11037                        continue;
11038                    }
11039                    if (!needSep) {
11040                        pw.println("  All known processes:");
11041                        needSep = true;
11042                        printedAnything = true;
11043                    }
11044                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11045                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11046                        pw.print(" "); pw.println(r);
11047                    r.dump(pw, "    ");
11048                    if (r.persistent) {
11049                        numPers++;
11050                    }
11051                }
11052            }
11053        }
11054
11055        if (mIsolatedProcesses.size() > 0) {
11056            boolean printed = false;
11057            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11058                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11059                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11060                    continue;
11061                }
11062                if (!printed) {
11063                    if (needSep) {
11064                        pw.println();
11065                    }
11066                    pw.println("  Isolated process list (sorted by uid):");
11067                    printedAnything = true;
11068                    printed = true;
11069                    needSep = true;
11070                }
11071                pw.println(String.format("%sIsolated #%2d: %s",
11072                        "    ", i, r.toString()));
11073            }
11074        }
11075
11076        if (mLruProcesses.size() > 0) {
11077            if (needSep) {
11078                pw.println();
11079            }
11080            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11081                    pw.print(" total, non-act at ");
11082                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11083                    pw.print(", non-svc at ");
11084                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11085                    pw.println("):");
11086            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11087            needSep = true;
11088            printedAnything = true;
11089        }
11090
11091        if (dumpAll || dumpPackage != null) {
11092            synchronized (mPidsSelfLocked) {
11093                boolean printed = false;
11094                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11095                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11096                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11097                        continue;
11098                    }
11099                    if (!printed) {
11100                        if (needSep) pw.println();
11101                        needSep = true;
11102                        pw.println("  PID mappings:");
11103                        printed = true;
11104                        printedAnything = true;
11105                    }
11106                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11107                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11108                }
11109            }
11110        }
11111
11112        if (mForegroundProcesses.size() > 0) {
11113            synchronized (mPidsSelfLocked) {
11114                boolean printed = false;
11115                for (int i=0; i<mForegroundProcesses.size(); i++) {
11116                    ProcessRecord r = mPidsSelfLocked.get(
11117                            mForegroundProcesses.valueAt(i).pid);
11118                    if (dumpPackage != null && (r == null
11119                            || !r.pkgList.containsKey(dumpPackage))) {
11120                        continue;
11121                    }
11122                    if (!printed) {
11123                        if (needSep) pw.println();
11124                        needSep = true;
11125                        pw.println("  Foreground Processes:");
11126                        printed = true;
11127                        printedAnything = true;
11128                    }
11129                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11130                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11131                }
11132            }
11133        }
11134
11135        if (mPersistentStartingProcesses.size() > 0) {
11136            if (needSep) pw.println();
11137            needSep = true;
11138            printedAnything = true;
11139            pw.println("  Persisent processes that are starting:");
11140            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11141                    "Starting Norm", "Restarting PERS", dumpPackage);
11142        }
11143
11144        if (mRemovedProcesses.size() > 0) {
11145            if (needSep) pw.println();
11146            needSep = true;
11147            printedAnything = true;
11148            pw.println("  Processes that are being removed:");
11149            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11150                    "Removed Norm", "Removed PERS", dumpPackage);
11151        }
11152
11153        if (mProcessesOnHold.size() > 0) {
11154            if (needSep) pw.println();
11155            needSep = true;
11156            printedAnything = true;
11157            pw.println("  Processes that are on old until the system is ready:");
11158            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11159                    "OnHold Norm", "OnHold PERS", dumpPackage);
11160        }
11161
11162        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11163
11164        if (mProcessCrashTimes.getMap().size() > 0) {
11165            boolean printed = false;
11166            long now = SystemClock.uptimeMillis();
11167            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11168            final int NP = pmap.size();
11169            for (int ip=0; ip<NP; ip++) {
11170                String pname = pmap.keyAt(ip);
11171                SparseArray<Long> uids = pmap.valueAt(ip);
11172                final int N = uids.size();
11173                for (int i=0; i<N; i++) {
11174                    int puid = uids.keyAt(i);
11175                    ProcessRecord r = mProcessNames.get(pname, puid);
11176                    if (dumpPackage != null && (r == null
11177                            || !r.pkgList.containsKey(dumpPackage))) {
11178                        continue;
11179                    }
11180                    if (!printed) {
11181                        if (needSep) pw.println();
11182                        needSep = true;
11183                        pw.println("  Time since processes crashed:");
11184                        printed = true;
11185                        printedAnything = true;
11186                    }
11187                    pw.print("    Process "); pw.print(pname);
11188                            pw.print(" uid "); pw.print(puid);
11189                            pw.print(": last crashed ");
11190                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11191                            pw.println(" ago");
11192                }
11193            }
11194        }
11195
11196        if (mBadProcesses.getMap().size() > 0) {
11197            boolean printed = false;
11198            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11199            final int NP = pmap.size();
11200            for (int ip=0; ip<NP; ip++) {
11201                String pname = pmap.keyAt(ip);
11202                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11203                final int N = uids.size();
11204                for (int i=0; i<N; i++) {
11205                    int puid = uids.keyAt(i);
11206                    ProcessRecord r = mProcessNames.get(pname, puid);
11207                    if (dumpPackage != null && (r == null
11208                            || !r.pkgList.containsKey(dumpPackage))) {
11209                        continue;
11210                    }
11211                    if (!printed) {
11212                        if (needSep) pw.println();
11213                        needSep = true;
11214                        pw.println("  Bad processes:");
11215                        printedAnything = true;
11216                    }
11217                    BadProcessInfo info = uids.valueAt(i);
11218                    pw.print("    Bad process "); pw.print(pname);
11219                            pw.print(" uid "); pw.print(puid);
11220                            pw.print(": crashed at time "); pw.println(info.time);
11221                    if (info.shortMsg != null) {
11222                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11223                    }
11224                    if (info.longMsg != null) {
11225                        pw.print("      Long msg: "); pw.println(info.longMsg);
11226                    }
11227                    if (info.stack != null) {
11228                        pw.println("      Stack:");
11229                        int lastPos = 0;
11230                        for (int pos=0; pos<info.stack.length(); pos++) {
11231                            if (info.stack.charAt(pos) == '\n') {
11232                                pw.print("        ");
11233                                pw.write(info.stack, lastPos, pos-lastPos);
11234                                pw.println();
11235                                lastPos = pos+1;
11236                            }
11237                        }
11238                        if (lastPos < info.stack.length()) {
11239                            pw.print("        ");
11240                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11241                            pw.println();
11242                        }
11243                    }
11244                }
11245            }
11246        }
11247
11248        if (dumpPackage == null) {
11249            pw.println();
11250            needSep = false;
11251            pw.println("  mStartedUsers:");
11252            for (int i=0; i<mStartedUsers.size(); i++) {
11253                UserStartedState uss = mStartedUsers.valueAt(i);
11254                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11255                        pw.print(": "); uss.dump("", pw);
11256            }
11257            pw.print("  mStartedUserArray: [");
11258            for (int i=0; i<mStartedUserArray.length; i++) {
11259                if (i > 0) pw.print(", ");
11260                pw.print(mStartedUserArray[i]);
11261            }
11262            pw.println("]");
11263            pw.print("  mUserLru: [");
11264            for (int i=0; i<mUserLru.size(); i++) {
11265                if (i > 0) pw.print(", ");
11266                pw.print(mUserLru.get(i));
11267            }
11268            pw.println("]");
11269            if (dumpAll) {
11270                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11271            }
11272        }
11273        if (mHomeProcess != null && (dumpPackage == null
11274                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11275            if (needSep) {
11276                pw.println();
11277                needSep = false;
11278            }
11279            pw.println("  mHomeProcess: " + mHomeProcess);
11280        }
11281        if (mPreviousProcess != null && (dumpPackage == null
11282                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11283            if (needSep) {
11284                pw.println();
11285                needSep = false;
11286            }
11287            pw.println("  mPreviousProcess: " + mPreviousProcess);
11288        }
11289        if (dumpAll) {
11290            StringBuilder sb = new StringBuilder(128);
11291            sb.append("  mPreviousProcessVisibleTime: ");
11292            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11293            pw.println(sb);
11294        }
11295        if (mHeavyWeightProcess != null && (dumpPackage == null
11296                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11297            if (needSep) {
11298                pw.println();
11299                needSep = false;
11300            }
11301            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11302        }
11303        if (dumpPackage == null) {
11304            pw.println("  mConfiguration: " + mConfiguration);
11305        }
11306        if (dumpAll) {
11307            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11308            if (mCompatModePackages.getPackages().size() > 0) {
11309                boolean printed = false;
11310                for (Map.Entry<String, Integer> entry
11311                        : mCompatModePackages.getPackages().entrySet()) {
11312                    String pkg = entry.getKey();
11313                    int mode = entry.getValue();
11314                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11315                        continue;
11316                    }
11317                    if (!printed) {
11318                        pw.println("  mScreenCompatPackages:");
11319                        printed = true;
11320                    }
11321                    pw.print("    "); pw.print(pkg); pw.print(": ");
11322                            pw.print(mode); pw.println();
11323                }
11324            }
11325        }
11326        if (dumpPackage == null) {
11327            if (mSleeping || mWentToSleep || mLockScreenShown) {
11328                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11329                        + " mLockScreenShown " + mLockScreenShown);
11330            }
11331            if (mShuttingDown || mRunningVoice) {
11332                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11333            }
11334        }
11335        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11336                || mOrigWaitForDebugger) {
11337            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11338                    || dumpPackage.equals(mOrigDebugApp)) {
11339                if (needSep) {
11340                    pw.println();
11341                    needSep = false;
11342                }
11343                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11344                        + " mDebugTransient=" + mDebugTransient
11345                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11346            }
11347        }
11348        if (mOpenGlTraceApp != null) {
11349            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11350                if (needSep) {
11351                    pw.println();
11352                    needSep = false;
11353                }
11354                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11355            }
11356        }
11357        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11358                || mProfileFd != null) {
11359            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11360                if (needSep) {
11361                    pw.println();
11362                    needSep = false;
11363                }
11364                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11365                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11366                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11367                        + mAutoStopProfiler);
11368            }
11369        }
11370        if (dumpPackage == null) {
11371            if (mAlwaysFinishActivities || mController != null) {
11372                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11373                        + " mController=" + mController);
11374            }
11375            if (dumpAll) {
11376                pw.println("  Total persistent processes: " + numPers);
11377                pw.println("  mProcessesReady=" + mProcessesReady
11378                        + " mSystemReady=" + mSystemReady);
11379                pw.println("  mBooting=" + mBooting
11380                        + " mBooted=" + mBooted
11381                        + " mFactoryTest=" + mFactoryTest);
11382                pw.print("  mLastPowerCheckRealtime=");
11383                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11384                        pw.println("");
11385                pw.print("  mLastPowerCheckUptime=");
11386                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11387                        pw.println("");
11388                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11389                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11390                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11391                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11392                        + " (" + mLruProcesses.size() + " total)"
11393                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11394                        + " mNumServiceProcs=" + mNumServiceProcs
11395                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11396                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11397                        + " mLastMemoryLevel" + mLastMemoryLevel
11398                        + " mLastNumProcesses" + mLastNumProcesses);
11399                long now = SystemClock.uptimeMillis();
11400                pw.print("  mLastIdleTime=");
11401                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11402                        pw.print(" mLowRamSinceLastIdle=");
11403                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11404                        pw.println();
11405            }
11406        }
11407
11408        if (!printedAnything) {
11409            pw.println("  (nothing)");
11410        }
11411    }
11412
11413    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11414            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11415        if (mProcessesToGc.size() > 0) {
11416            boolean printed = false;
11417            long now = SystemClock.uptimeMillis();
11418            for (int i=0; i<mProcessesToGc.size(); i++) {
11419                ProcessRecord proc = mProcessesToGc.get(i);
11420                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11421                    continue;
11422                }
11423                if (!printed) {
11424                    if (needSep) pw.println();
11425                    needSep = true;
11426                    pw.println("  Processes that are waiting to GC:");
11427                    printed = true;
11428                }
11429                pw.print("    Process "); pw.println(proc);
11430                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11431                        pw.print(", last gced=");
11432                        pw.print(now-proc.lastRequestedGc);
11433                        pw.print(" ms ago, last lowMem=");
11434                        pw.print(now-proc.lastLowMemory);
11435                        pw.println(" ms ago");
11436
11437            }
11438        }
11439        return needSep;
11440    }
11441
11442    void printOomLevel(PrintWriter pw, String name, int adj) {
11443        pw.print("    ");
11444        if (adj >= 0) {
11445            pw.print(' ');
11446            if (adj < 10) pw.print(' ');
11447        } else {
11448            if (adj > -10) pw.print(' ');
11449        }
11450        pw.print(adj);
11451        pw.print(": ");
11452        pw.print(name);
11453        pw.print(" (");
11454        pw.print(mProcessList.getMemLevel(adj)/1024);
11455        pw.println(" kB)");
11456    }
11457
11458    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11459            int opti, boolean dumpAll) {
11460        boolean needSep = false;
11461
11462        if (mLruProcesses.size() > 0) {
11463            if (needSep) pw.println();
11464            needSep = true;
11465            pw.println("  OOM levels:");
11466            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11467            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11468            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11469            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11470            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11471            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11472            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11473            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11474            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11475            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11476            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11477            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11478            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11479
11480            if (needSep) pw.println();
11481            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11482                    pw.print(" total, non-act at ");
11483                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11484                    pw.print(", non-svc at ");
11485                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11486                    pw.println("):");
11487            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11488            needSep = true;
11489        }
11490
11491        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11492
11493        pw.println();
11494        pw.println("  mHomeProcess: " + mHomeProcess);
11495        pw.println("  mPreviousProcess: " + mPreviousProcess);
11496        if (mHeavyWeightProcess != null) {
11497            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11498        }
11499
11500        return true;
11501    }
11502
11503    /**
11504     * There are three ways to call this:
11505     *  - no provider specified: dump all the providers
11506     *  - a flattened component name that matched an existing provider was specified as the
11507     *    first arg: dump that one provider
11508     *  - the first arg isn't the flattened component name of an existing provider:
11509     *    dump all providers whose component contains the first arg as a substring
11510     */
11511    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11512            int opti, boolean dumpAll) {
11513        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11514    }
11515
11516    static class ItemMatcher {
11517        ArrayList<ComponentName> components;
11518        ArrayList<String> strings;
11519        ArrayList<Integer> objects;
11520        boolean all;
11521
11522        ItemMatcher() {
11523            all = true;
11524        }
11525
11526        void build(String name) {
11527            ComponentName componentName = ComponentName.unflattenFromString(name);
11528            if (componentName != null) {
11529                if (components == null) {
11530                    components = new ArrayList<ComponentName>();
11531                }
11532                components.add(componentName);
11533                all = false;
11534            } else {
11535                int objectId = 0;
11536                // Not a '/' separated full component name; maybe an object ID?
11537                try {
11538                    objectId = Integer.parseInt(name, 16);
11539                    if (objects == null) {
11540                        objects = new ArrayList<Integer>();
11541                    }
11542                    objects.add(objectId);
11543                    all = false;
11544                } catch (RuntimeException e) {
11545                    // Not an integer; just do string match.
11546                    if (strings == null) {
11547                        strings = new ArrayList<String>();
11548                    }
11549                    strings.add(name);
11550                    all = false;
11551                }
11552            }
11553        }
11554
11555        int build(String[] args, int opti) {
11556            for (; opti<args.length; opti++) {
11557                String name = args[opti];
11558                if ("--".equals(name)) {
11559                    return opti+1;
11560                }
11561                build(name);
11562            }
11563            return opti;
11564        }
11565
11566        boolean match(Object object, ComponentName comp) {
11567            if (all) {
11568                return true;
11569            }
11570            if (components != null) {
11571                for (int i=0; i<components.size(); i++) {
11572                    if (components.get(i).equals(comp)) {
11573                        return true;
11574                    }
11575                }
11576            }
11577            if (objects != null) {
11578                for (int i=0; i<objects.size(); i++) {
11579                    if (System.identityHashCode(object) == objects.get(i)) {
11580                        return true;
11581                    }
11582                }
11583            }
11584            if (strings != null) {
11585                String flat = comp.flattenToString();
11586                for (int i=0; i<strings.size(); i++) {
11587                    if (flat.contains(strings.get(i))) {
11588                        return true;
11589                    }
11590                }
11591            }
11592            return false;
11593        }
11594    }
11595
11596    /**
11597     * There are three things that cmd can be:
11598     *  - a flattened component name that matches an existing activity
11599     *  - the cmd arg isn't the flattened component name of an existing activity:
11600     *    dump all activity whose component contains the cmd as a substring
11601     *  - A hex number of the ActivityRecord object instance.
11602     */
11603    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11604            int opti, boolean dumpAll) {
11605        ArrayList<ActivityRecord> activities;
11606
11607        synchronized (this) {
11608            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11609        }
11610
11611        if (activities.size() <= 0) {
11612            return false;
11613        }
11614
11615        String[] newArgs = new String[args.length - opti];
11616        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11617
11618        TaskRecord lastTask = null;
11619        boolean needSep = false;
11620        for (int i=activities.size()-1; i>=0; i--) {
11621            ActivityRecord r = activities.get(i);
11622            if (needSep) {
11623                pw.println();
11624            }
11625            needSep = true;
11626            synchronized (this) {
11627                if (lastTask != r.task) {
11628                    lastTask = r.task;
11629                    pw.print("TASK "); pw.print(lastTask.affinity);
11630                            pw.print(" id="); pw.println(lastTask.taskId);
11631                    if (dumpAll) {
11632                        lastTask.dump(pw, "  ");
11633                    }
11634                }
11635            }
11636            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11637        }
11638        return true;
11639    }
11640
11641    /**
11642     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11643     * there is a thread associated with the activity.
11644     */
11645    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11646            final ActivityRecord r, String[] args, boolean dumpAll) {
11647        String innerPrefix = prefix + "  ";
11648        synchronized (this) {
11649            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11650                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11651                    pw.print(" pid=");
11652                    if (r.app != null) pw.println(r.app.pid);
11653                    else pw.println("(not running)");
11654            if (dumpAll) {
11655                r.dump(pw, innerPrefix);
11656            }
11657        }
11658        if (r.app != null && r.app.thread != null) {
11659            // flush anything that is already in the PrintWriter since the thread is going
11660            // to write to the file descriptor directly
11661            pw.flush();
11662            try {
11663                TransferPipe tp = new TransferPipe();
11664                try {
11665                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11666                            r.appToken, innerPrefix, args);
11667                    tp.go(fd);
11668                } finally {
11669                    tp.kill();
11670                }
11671            } catch (IOException e) {
11672                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11673            } catch (RemoteException e) {
11674                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11675            }
11676        }
11677    }
11678
11679    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11680            int opti, boolean dumpAll, String dumpPackage) {
11681        boolean needSep = false;
11682        boolean onlyHistory = false;
11683        boolean printedAnything = false;
11684
11685        if ("history".equals(dumpPackage)) {
11686            if (opti < args.length && "-s".equals(args[opti])) {
11687                dumpAll = false;
11688            }
11689            onlyHistory = true;
11690            dumpPackage = null;
11691        }
11692
11693        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11694        if (!onlyHistory && dumpAll) {
11695            if (mRegisteredReceivers.size() > 0) {
11696                boolean printed = false;
11697                Iterator it = mRegisteredReceivers.values().iterator();
11698                while (it.hasNext()) {
11699                    ReceiverList r = (ReceiverList)it.next();
11700                    if (dumpPackage != null && (r.app == null ||
11701                            !dumpPackage.equals(r.app.info.packageName))) {
11702                        continue;
11703                    }
11704                    if (!printed) {
11705                        pw.println("  Registered Receivers:");
11706                        needSep = true;
11707                        printed = true;
11708                        printedAnything = true;
11709                    }
11710                    pw.print("  * "); pw.println(r);
11711                    r.dump(pw, "    ");
11712                }
11713            }
11714
11715            if (mReceiverResolver.dump(pw, needSep ?
11716                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11717                    "    ", dumpPackage, false)) {
11718                needSep = true;
11719                printedAnything = true;
11720            }
11721        }
11722
11723        for (BroadcastQueue q : mBroadcastQueues) {
11724            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11725            printedAnything |= needSep;
11726        }
11727
11728        needSep = true;
11729
11730        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11731            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11732                if (needSep) {
11733                    pw.println();
11734                }
11735                needSep = true;
11736                printedAnything = true;
11737                pw.print("  Sticky broadcasts for user ");
11738                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11739                StringBuilder sb = new StringBuilder(128);
11740                for (Map.Entry<String, ArrayList<Intent>> ent
11741                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11742                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11743                    if (dumpAll) {
11744                        pw.println(":");
11745                        ArrayList<Intent> intents = ent.getValue();
11746                        final int N = intents.size();
11747                        for (int i=0; i<N; i++) {
11748                            sb.setLength(0);
11749                            sb.append("    Intent: ");
11750                            intents.get(i).toShortString(sb, false, true, false, false);
11751                            pw.println(sb.toString());
11752                            Bundle bundle = intents.get(i).getExtras();
11753                            if (bundle != null) {
11754                                pw.print("      ");
11755                                pw.println(bundle.toString());
11756                            }
11757                        }
11758                    } else {
11759                        pw.println("");
11760                    }
11761                }
11762            }
11763        }
11764
11765        if (!onlyHistory && dumpAll) {
11766            pw.println();
11767            for (BroadcastQueue queue : mBroadcastQueues) {
11768                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11769                        + queue.mBroadcastsScheduled);
11770            }
11771            pw.println("  mHandler:");
11772            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11773            needSep = true;
11774            printedAnything = true;
11775        }
11776
11777        if (!printedAnything) {
11778            pw.println("  (nothing)");
11779        }
11780    }
11781
11782    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11783            int opti, boolean dumpAll, String dumpPackage) {
11784        boolean needSep;
11785        boolean printedAnything = false;
11786
11787        ItemMatcher matcher = new ItemMatcher();
11788        matcher.build(args, opti);
11789
11790        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11791
11792        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11793        printedAnything |= needSep;
11794
11795        if (mLaunchingProviders.size() > 0) {
11796            boolean printed = false;
11797            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11798                ContentProviderRecord r = mLaunchingProviders.get(i);
11799                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11800                    continue;
11801                }
11802                if (!printed) {
11803                    if (needSep) pw.println();
11804                    needSep = true;
11805                    pw.println("  Launching content providers:");
11806                    printed = true;
11807                    printedAnything = true;
11808                }
11809                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11810                        pw.println(r);
11811            }
11812        }
11813
11814        if (mGrantedUriPermissions.size() > 0) {
11815            boolean printed = false;
11816            int dumpUid = -2;
11817            if (dumpPackage != null) {
11818                try {
11819                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11820                } catch (NameNotFoundException e) {
11821                    dumpUid = -1;
11822                }
11823            }
11824            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11825                int uid = mGrantedUriPermissions.keyAt(i);
11826                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11827                    continue;
11828                }
11829                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11830                if (!printed) {
11831                    if (needSep) pw.println();
11832                    needSep = true;
11833                    pw.println("  Granted Uri Permissions:");
11834                    printed = true;
11835                    printedAnything = true;
11836                }
11837                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11838                for (UriPermission perm : perms.values()) {
11839                    pw.print("    "); pw.println(perm);
11840                    if (dumpAll) {
11841                        perm.dump(pw, "      ");
11842                    }
11843                }
11844            }
11845        }
11846
11847        if (!printedAnything) {
11848            pw.println("  (nothing)");
11849        }
11850    }
11851
11852    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11853            int opti, boolean dumpAll, String dumpPackage) {
11854        boolean printed = false;
11855
11856        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11857
11858        if (mIntentSenderRecords.size() > 0) {
11859            Iterator<WeakReference<PendingIntentRecord>> it
11860                    = mIntentSenderRecords.values().iterator();
11861            while (it.hasNext()) {
11862                WeakReference<PendingIntentRecord> ref = it.next();
11863                PendingIntentRecord rec = ref != null ? ref.get(): null;
11864                if (dumpPackage != null && (rec == null
11865                        || !dumpPackage.equals(rec.key.packageName))) {
11866                    continue;
11867                }
11868                printed = true;
11869                if (rec != null) {
11870                    pw.print("  * "); pw.println(rec);
11871                    if (dumpAll) {
11872                        rec.dump(pw, "    ");
11873                    }
11874                } else {
11875                    pw.print("  * "); pw.println(ref);
11876                }
11877            }
11878        }
11879
11880        if (!printed) {
11881            pw.println("  (nothing)");
11882        }
11883    }
11884
11885    private static final int dumpProcessList(PrintWriter pw,
11886            ActivityManagerService service, List list,
11887            String prefix, String normalLabel, String persistentLabel,
11888            String dumpPackage) {
11889        int numPers = 0;
11890        final int N = list.size()-1;
11891        for (int i=N; i>=0; i--) {
11892            ProcessRecord r = (ProcessRecord)list.get(i);
11893            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11894                continue;
11895            }
11896            pw.println(String.format("%s%s #%2d: %s",
11897                    prefix, (r.persistent ? persistentLabel : normalLabel),
11898                    i, r.toString()));
11899            if (r.persistent) {
11900                numPers++;
11901            }
11902        }
11903        return numPers;
11904    }
11905
11906    private static final boolean dumpProcessOomList(PrintWriter pw,
11907            ActivityManagerService service, List<ProcessRecord> origList,
11908            String prefix, String normalLabel, String persistentLabel,
11909            boolean inclDetails, String dumpPackage) {
11910
11911        ArrayList<Pair<ProcessRecord, Integer>> list
11912                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11913        for (int i=0; i<origList.size(); i++) {
11914            ProcessRecord r = origList.get(i);
11915            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11916                continue;
11917            }
11918            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11919        }
11920
11921        if (list.size() <= 0) {
11922            return false;
11923        }
11924
11925        Comparator<Pair<ProcessRecord, Integer>> comparator
11926                = new Comparator<Pair<ProcessRecord, Integer>>() {
11927            @Override
11928            public int compare(Pair<ProcessRecord, Integer> object1,
11929                    Pair<ProcessRecord, Integer> object2) {
11930                if (object1.first.setAdj != object2.first.setAdj) {
11931                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11932                }
11933                if (object1.second.intValue() != object2.second.intValue()) {
11934                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11935                }
11936                return 0;
11937            }
11938        };
11939
11940        Collections.sort(list, comparator);
11941
11942        final long curRealtime = SystemClock.elapsedRealtime();
11943        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11944        final long curUptime = SystemClock.uptimeMillis();
11945        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11946
11947        for (int i=list.size()-1; i>=0; i--) {
11948            ProcessRecord r = list.get(i).first;
11949            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11950            char schedGroup;
11951            switch (r.setSchedGroup) {
11952                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11953                    schedGroup = 'B';
11954                    break;
11955                case Process.THREAD_GROUP_DEFAULT:
11956                    schedGroup = 'F';
11957                    break;
11958                default:
11959                    schedGroup = '?';
11960                    break;
11961            }
11962            char foreground;
11963            if (r.foregroundActivities) {
11964                foreground = 'A';
11965            } else if (r.foregroundServices) {
11966                foreground = 'S';
11967            } else {
11968                foreground = ' ';
11969            }
11970            String procState = ProcessList.makeProcStateString(r.curProcState);
11971            pw.print(prefix);
11972            pw.print(r.persistent ? persistentLabel : normalLabel);
11973            pw.print(" #");
11974            int num = (origList.size()-1)-list.get(i).second;
11975            if (num < 10) pw.print(' ');
11976            pw.print(num);
11977            pw.print(": ");
11978            pw.print(oomAdj);
11979            pw.print(' ');
11980            pw.print(schedGroup);
11981            pw.print('/');
11982            pw.print(foreground);
11983            pw.print('/');
11984            pw.print(procState);
11985            pw.print(" trm:");
11986            if (r.trimMemoryLevel < 10) pw.print(' ');
11987            pw.print(r.trimMemoryLevel);
11988            pw.print(' ');
11989            pw.print(r.toShortString());
11990            pw.print(" (");
11991            pw.print(r.adjType);
11992            pw.println(')');
11993            if (r.adjSource != null || r.adjTarget != null) {
11994                pw.print(prefix);
11995                pw.print("    ");
11996                if (r.adjTarget instanceof ComponentName) {
11997                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11998                } else if (r.adjTarget != null) {
11999                    pw.print(r.adjTarget.toString());
12000                } else {
12001                    pw.print("{null}");
12002                }
12003                pw.print("<=");
12004                if (r.adjSource instanceof ProcessRecord) {
12005                    pw.print("Proc{");
12006                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12007                    pw.println("}");
12008                } else if (r.adjSource != null) {
12009                    pw.println(r.adjSource.toString());
12010                } else {
12011                    pw.println("{null}");
12012                }
12013            }
12014            if (inclDetails) {
12015                pw.print(prefix);
12016                pw.print("    ");
12017                pw.print("oom: max="); pw.print(r.maxAdj);
12018                pw.print(" curRaw="); pw.print(r.curRawAdj);
12019                pw.print(" setRaw="); pw.print(r.setRawAdj);
12020                pw.print(" cur="); pw.print(r.curAdj);
12021                pw.print(" set="); pw.println(r.setAdj);
12022                pw.print(prefix);
12023                pw.print("    ");
12024                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12025                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12026                pw.print(" lastPss="); pw.print(r.lastPss);
12027                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12028                pw.print(prefix);
12029                pw.print("    ");
12030                pw.print("keeping="); pw.print(r.keeping);
12031                pw.print(" cached="); pw.print(r.cached);
12032                pw.print(" empty="); pw.print(r.empty);
12033                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12034
12035                if (!r.keeping) {
12036                    if (r.lastWakeTime != 0) {
12037                        long wtime;
12038                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12039                        synchronized (stats) {
12040                            wtime = stats.getProcessWakeTime(r.info.uid,
12041                                    r.pid, curRealtime);
12042                        }
12043                        long timeUsed = wtime - r.lastWakeTime;
12044                        pw.print(prefix);
12045                        pw.print("    ");
12046                        pw.print("keep awake over ");
12047                        TimeUtils.formatDuration(realtimeSince, pw);
12048                        pw.print(" used ");
12049                        TimeUtils.formatDuration(timeUsed, pw);
12050                        pw.print(" (");
12051                        pw.print((timeUsed*100)/realtimeSince);
12052                        pw.println("%)");
12053                    }
12054                    if (r.lastCpuTime != 0) {
12055                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12056                        pw.print(prefix);
12057                        pw.print("    ");
12058                        pw.print("run cpu over ");
12059                        TimeUtils.formatDuration(uptimeSince, pw);
12060                        pw.print(" used ");
12061                        TimeUtils.formatDuration(timeUsed, pw);
12062                        pw.print(" (");
12063                        pw.print((timeUsed*100)/uptimeSince);
12064                        pw.println("%)");
12065                    }
12066                }
12067            }
12068        }
12069        return true;
12070    }
12071
12072    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12073        ArrayList<ProcessRecord> procs;
12074        synchronized (this) {
12075            if (args != null && args.length > start
12076                    && args[start].charAt(0) != '-') {
12077                procs = new ArrayList<ProcessRecord>();
12078                int pid = -1;
12079                try {
12080                    pid = Integer.parseInt(args[start]);
12081                } catch (NumberFormatException e) {
12082                }
12083                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12084                    ProcessRecord proc = mLruProcesses.get(i);
12085                    if (proc.pid == pid) {
12086                        procs.add(proc);
12087                    } else if (proc.processName.equals(args[start])) {
12088                        procs.add(proc);
12089                    }
12090                }
12091                if (procs.size() <= 0) {
12092                    return null;
12093                }
12094            } else {
12095                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12096            }
12097        }
12098        return procs;
12099    }
12100
12101    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12102            PrintWriter pw, String[] args) {
12103        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12104        if (procs == null) {
12105            pw.println("No process found for: " + args[0]);
12106            return;
12107        }
12108
12109        long uptime = SystemClock.uptimeMillis();
12110        long realtime = SystemClock.elapsedRealtime();
12111        pw.println("Applications Graphics Acceleration Info:");
12112        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12113
12114        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12115            ProcessRecord r = procs.get(i);
12116            if (r.thread != null) {
12117                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12118                pw.flush();
12119                try {
12120                    TransferPipe tp = new TransferPipe();
12121                    try {
12122                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12123                        tp.go(fd);
12124                    } finally {
12125                        tp.kill();
12126                    }
12127                } catch (IOException e) {
12128                    pw.println("Failure while dumping the app: " + r);
12129                    pw.flush();
12130                } catch (RemoteException e) {
12131                    pw.println("Got a RemoteException while dumping the app " + r);
12132                    pw.flush();
12133                }
12134            }
12135        }
12136    }
12137
12138    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12139        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12140        if (procs == null) {
12141            pw.println("No process found for: " + args[0]);
12142            return;
12143        }
12144
12145        pw.println("Applications Database Info:");
12146
12147        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12148            ProcessRecord r = procs.get(i);
12149            if (r.thread != null) {
12150                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12151                pw.flush();
12152                try {
12153                    TransferPipe tp = new TransferPipe();
12154                    try {
12155                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12156                        tp.go(fd);
12157                    } finally {
12158                        tp.kill();
12159                    }
12160                } catch (IOException e) {
12161                    pw.println("Failure while dumping the app: " + r);
12162                    pw.flush();
12163                } catch (RemoteException e) {
12164                    pw.println("Got a RemoteException while dumping the app " + r);
12165                    pw.flush();
12166                }
12167            }
12168        }
12169    }
12170
12171    final static class MemItem {
12172        final boolean isProc;
12173        final String label;
12174        final String shortLabel;
12175        final long pss;
12176        final int id;
12177        final boolean hasActivities;
12178        ArrayList<MemItem> subitems;
12179
12180        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12181                boolean _hasActivities) {
12182            isProc = true;
12183            label = _label;
12184            shortLabel = _shortLabel;
12185            pss = _pss;
12186            id = _id;
12187            hasActivities = _hasActivities;
12188        }
12189
12190        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12191            isProc = false;
12192            label = _label;
12193            shortLabel = _shortLabel;
12194            pss = _pss;
12195            id = _id;
12196            hasActivities = false;
12197        }
12198    }
12199
12200    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12201            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12202        if (sort && !isCompact) {
12203            Collections.sort(items, new Comparator<MemItem>() {
12204                @Override
12205                public int compare(MemItem lhs, MemItem rhs) {
12206                    if (lhs.pss < rhs.pss) {
12207                        return 1;
12208                    } else if (lhs.pss > rhs.pss) {
12209                        return -1;
12210                    }
12211                    return 0;
12212                }
12213            });
12214        }
12215
12216        for (int i=0; i<items.size(); i++) {
12217            MemItem mi = items.get(i);
12218            if (!isCompact) {
12219                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12220            } else if (mi.isProc) {
12221                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12222                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12223                pw.println(mi.hasActivities ? ",a" : ",e");
12224            } else {
12225                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12226                pw.println(mi.pss);
12227            }
12228            if (mi.subitems != null) {
12229                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12230                        true, isCompact);
12231            }
12232        }
12233    }
12234
12235    // These are in KB.
12236    static final long[] DUMP_MEM_BUCKETS = new long[] {
12237        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12238        120*1024, 160*1024, 200*1024,
12239        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12240        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12241    };
12242
12243    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12244            boolean stackLike) {
12245        int start = label.lastIndexOf('.');
12246        if (start >= 0) start++;
12247        else start = 0;
12248        int end = label.length();
12249        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12250            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12251                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12252                out.append(bucket);
12253                out.append(stackLike ? "MB." : "MB ");
12254                out.append(label, start, end);
12255                return;
12256            }
12257        }
12258        out.append(memKB/1024);
12259        out.append(stackLike ? "MB." : "MB ");
12260        out.append(label, start, end);
12261    }
12262
12263    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12264            ProcessList.NATIVE_ADJ,
12265            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12266            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12267            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12268            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12269            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12270    };
12271    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12272            "Native",
12273            "System", "Persistent", "Foreground",
12274            "Visible", "Perceptible",
12275            "Heavy Weight", "Backup",
12276            "A Services", "Home",
12277            "Previous", "B Services", "Cached"
12278    };
12279    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12280            "native",
12281            "sys", "pers", "fore",
12282            "vis", "percept",
12283            "heavy", "backup",
12284            "servicea", "home",
12285            "prev", "serviceb", "cached"
12286    };
12287
12288    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12289            long realtime, boolean isCheckinRequest, boolean isCompact) {
12290        if (isCheckinRequest || isCompact) {
12291            // short checkin version
12292            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12293        } else {
12294            pw.println("Applications Memory Usage (kB):");
12295            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12296        }
12297    }
12298
12299    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12300            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12301        boolean dumpDetails = false;
12302        boolean dumpFullDetails = false;
12303        boolean dumpDalvik = false;
12304        boolean oomOnly = false;
12305        boolean isCompact = false;
12306        boolean localOnly = false;
12307
12308        int opti = 0;
12309        while (opti < args.length) {
12310            String opt = args[opti];
12311            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12312                break;
12313            }
12314            opti++;
12315            if ("-a".equals(opt)) {
12316                dumpDetails = true;
12317                dumpFullDetails = true;
12318                dumpDalvik = true;
12319            } else if ("-d".equals(opt)) {
12320                dumpDalvik = true;
12321            } else if ("-c".equals(opt)) {
12322                isCompact = true;
12323            } else if ("--oom".equals(opt)) {
12324                oomOnly = true;
12325            } else if ("--local".equals(opt)) {
12326                localOnly = true;
12327            } else if ("-h".equals(opt)) {
12328                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12329                pw.println("  -a: include all available information for each process.");
12330                pw.println("  -d: include dalvik details when dumping process details.");
12331                pw.println("  -c: dump in a compact machine-parseable representation.");
12332                pw.println("  --oom: only show processes organized by oom adj.");
12333                pw.println("  --local: only collect details locally, don't call process.");
12334                pw.println("If [process] is specified it can be the name or ");
12335                pw.println("pid of a specific process to dump.");
12336                return;
12337            } else {
12338                pw.println("Unknown argument: " + opt + "; use -h for help");
12339            }
12340        }
12341
12342        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12343        long uptime = SystemClock.uptimeMillis();
12344        long realtime = SystemClock.elapsedRealtime();
12345        final long[] tmpLong = new long[1];
12346
12347        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12348        if (procs == null) {
12349            // No Java processes.  Maybe they want to print a native process.
12350            if (args != null && args.length > opti
12351                    && args[opti].charAt(0) != '-') {
12352                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12353                        = new ArrayList<ProcessCpuTracker.Stats>();
12354                updateCpuStatsNow();
12355                int findPid = -1;
12356                try {
12357                    findPid = Integer.parseInt(args[opti]);
12358                } catch (NumberFormatException e) {
12359                }
12360                synchronized (mProcessCpuThread) {
12361                    final int N = mProcessCpuTracker.countStats();
12362                    for (int i=0; i<N; i++) {
12363                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12364                        if (st.pid == findPid || (st.baseName != null
12365                                && st.baseName.equals(args[opti]))) {
12366                            nativeProcs.add(st);
12367                        }
12368                    }
12369                }
12370                if (nativeProcs.size() > 0) {
12371                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12372                            isCompact);
12373                    Debug.MemoryInfo mi = null;
12374                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12375                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12376                        final int pid = r.pid;
12377                        if (!isCheckinRequest && dumpDetails) {
12378                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12379                        }
12380                        if (mi == null) {
12381                            mi = new Debug.MemoryInfo();
12382                        }
12383                        if (dumpDetails || (!brief && !oomOnly)) {
12384                            Debug.getMemoryInfo(pid, mi);
12385                        } else {
12386                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12387                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12388                        }
12389                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12390                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12391                        if (isCheckinRequest) {
12392                            pw.println();
12393                        }
12394                    }
12395                    return;
12396                }
12397            }
12398            pw.println("No process found for: " + args[opti]);
12399            return;
12400        }
12401
12402        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12403            dumpDetails = true;
12404        }
12405
12406        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12407
12408        String[] innerArgs = new String[args.length-opti];
12409        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12410
12411        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12412        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12413        long nativePss=0, dalvikPss=0, otherPss=0;
12414        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12415
12416        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12417        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12418                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12419
12420        long totalPss = 0;
12421        long cachedPss = 0;
12422
12423        Debug.MemoryInfo mi = null;
12424        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12425            final ProcessRecord r = procs.get(i);
12426            final IApplicationThread thread;
12427            final int pid;
12428            final int oomAdj;
12429            final boolean hasActivities;
12430            synchronized (this) {
12431                thread = r.thread;
12432                pid = r.pid;
12433                oomAdj = r.getSetAdjWithServices();
12434                hasActivities = r.activities.size() > 0;
12435            }
12436            if (thread != null) {
12437                if (!isCheckinRequest && dumpDetails) {
12438                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12439                }
12440                if (mi == null) {
12441                    mi = new Debug.MemoryInfo();
12442                }
12443                if (dumpDetails || (!brief && !oomOnly)) {
12444                    Debug.getMemoryInfo(pid, mi);
12445                } else {
12446                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12447                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12448                }
12449                if (dumpDetails) {
12450                    if (localOnly) {
12451                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12452                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12453                        if (isCheckinRequest) {
12454                            pw.println();
12455                        }
12456                    } else {
12457                        try {
12458                            pw.flush();
12459                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12460                                    dumpDalvik, innerArgs);
12461                        } catch (RemoteException e) {
12462                            if (!isCheckinRequest) {
12463                                pw.println("Got RemoteException!");
12464                                pw.flush();
12465                            }
12466                        }
12467                    }
12468                }
12469
12470                final long myTotalPss = mi.getTotalPss();
12471                final long myTotalUss = mi.getTotalUss();
12472
12473                synchronized (this) {
12474                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12475                        // Record this for posterity if the process has been stable.
12476                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12477                    }
12478                }
12479
12480                if (!isCheckinRequest && mi != null) {
12481                    totalPss += myTotalPss;
12482                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12483                            (hasActivities ? " / activities)" : ")"),
12484                            r.processName, myTotalPss, pid, hasActivities);
12485                    procMems.add(pssItem);
12486                    procMemsMap.put(pid, pssItem);
12487
12488                    nativePss += mi.nativePss;
12489                    dalvikPss += mi.dalvikPss;
12490                    otherPss += mi.otherPss;
12491                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12492                        long mem = mi.getOtherPss(j);
12493                        miscPss[j] += mem;
12494                        otherPss -= mem;
12495                    }
12496
12497                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12498                        cachedPss += myTotalPss;
12499                    }
12500
12501                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12502                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12503                                || oomIndex == (oomPss.length-1)) {
12504                            oomPss[oomIndex] += myTotalPss;
12505                            if (oomProcs[oomIndex] == null) {
12506                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12507                            }
12508                            oomProcs[oomIndex].add(pssItem);
12509                            break;
12510                        }
12511                    }
12512                }
12513            }
12514        }
12515
12516        if (!isCheckinRequest && procs.size() > 1) {
12517            // If we are showing aggregations, also look for native processes to
12518            // include so that our aggregations are more accurate.
12519            updateCpuStatsNow();
12520            synchronized (mProcessCpuThread) {
12521                final int N = mProcessCpuTracker.countStats();
12522                for (int i=0; i<N; i++) {
12523                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12524                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12525                        if (mi == null) {
12526                            mi = new Debug.MemoryInfo();
12527                        }
12528                        if (!brief && !oomOnly) {
12529                            Debug.getMemoryInfo(st.pid, mi);
12530                        } else {
12531                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12532                            mi.nativePrivateDirty = (int)tmpLong[0];
12533                        }
12534
12535                        final long myTotalPss = mi.getTotalPss();
12536                        totalPss += myTotalPss;
12537
12538                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12539                                st.name, myTotalPss, st.pid, false);
12540                        procMems.add(pssItem);
12541
12542                        nativePss += mi.nativePss;
12543                        dalvikPss += mi.dalvikPss;
12544                        otherPss += mi.otherPss;
12545                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12546                            long mem = mi.getOtherPss(j);
12547                            miscPss[j] += mem;
12548                            otherPss -= mem;
12549                        }
12550                        oomPss[0] += myTotalPss;
12551                        if (oomProcs[0] == null) {
12552                            oomProcs[0] = new ArrayList<MemItem>();
12553                        }
12554                        oomProcs[0].add(pssItem);
12555                    }
12556                }
12557            }
12558
12559            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12560
12561            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12562            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12563            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12564            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12565                String label = Debug.MemoryInfo.getOtherLabel(j);
12566                catMems.add(new MemItem(label, label, miscPss[j], j));
12567            }
12568
12569            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12570            for (int j=0; j<oomPss.length; j++) {
12571                if (oomPss[j] != 0) {
12572                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12573                            : DUMP_MEM_OOM_LABEL[j];
12574                    MemItem item = new MemItem(label, label, oomPss[j],
12575                            DUMP_MEM_OOM_ADJ[j]);
12576                    item.subitems = oomProcs[j];
12577                    oomMems.add(item);
12578                }
12579            }
12580
12581            if (!brief && !oomOnly && !isCompact) {
12582                pw.println();
12583                pw.println("Total PSS by process:");
12584                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12585                pw.println();
12586            }
12587            if (!isCompact) {
12588                pw.println("Total PSS by OOM adjustment:");
12589            }
12590            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12591            if (!brief && !oomOnly) {
12592                PrintWriter out = categoryPw != null ? categoryPw : pw;
12593                if (!isCompact) {
12594                    out.println();
12595                    out.println("Total PSS by category:");
12596                }
12597                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12598            }
12599            if (!isCompact) {
12600                pw.println();
12601            }
12602            MemInfoReader memInfo = new MemInfoReader();
12603            memInfo.readMemInfo();
12604            if (!brief) {
12605                if (!isCompact) {
12606                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12607                    pw.print(" kB (status ");
12608                    switch (mLastMemoryLevel) {
12609                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12610                            pw.println("normal)");
12611                            break;
12612                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12613                            pw.println("moderate)");
12614                            break;
12615                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12616                            pw.println("low)");
12617                            break;
12618                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12619                            pw.println("critical)");
12620                            break;
12621                        default:
12622                            pw.print(mLastMemoryLevel);
12623                            pw.println(")");
12624                            break;
12625                    }
12626                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12627                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12628                            pw.print(cachedPss); pw.print(" cached pss + ");
12629                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12630                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12631                } else {
12632                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12633                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12634                            + memInfo.getFreeSizeKb()); pw.print(",");
12635                    pw.println(totalPss - cachedPss);
12636                }
12637            }
12638            if (!isCompact) {
12639                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12640                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12641                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12642                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12643                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12644                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12645                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12646                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12647                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12648                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12649                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12650            }
12651            if (!brief) {
12652                if (memInfo.getZramTotalSizeKb() != 0) {
12653                    if (!isCompact) {
12654                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12655                                pw.print(" kB physical used for ");
12656                                pw.print(memInfo.getSwapTotalSizeKb()
12657                                        - memInfo.getSwapFreeSizeKb());
12658                                pw.print(" kB in swap (");
12659                                pw.print(memInfo.getSwapTotalSizeKb());
12660                                pw.println(" kB total swap)");
12661                    } else {
12662                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12663                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12664                                pw.println(memInfo.getSwapFreeSizeKb());
12665                    }
12666                }
12667                final int[] SINGLE_LONG_FORMAT = new int[] {
12668                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12669                };
12670                long[] longOut = new long[1];
12671                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12672                        SINGLE_LONG_FORMAT, null, longOut, null);
12673                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12674                longOut[0] = 0;
12675                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12676                        SINGLE_LONG_FORMAT, null, longOut, null);
12677                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12678                longOut[0] = 0;
12679                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12680                        SINGLE_LONG_FORMAT, null, longOut, null);
12681                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12682                longOut[0] = 0;
12683                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12684                        SINGLE_LONG_FORMAT, null, longOut, null);
12685                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12686                if (!isCompact) {
12687                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12688                        pw.print("      KSM: "); pw.print(sharing);
12689                                pw.print(" kB saved from shared ");
12690                                pw.print(shared); pw.println(" kB");
12691                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12692                                pw.print(voltile); pw.println(" kB volatile");
12693                    }
12694                    pw.print("   Tuning: ");
12695                    pw.print(ActivityManager.staticGetMemoryClass());
12696                    pw.print(" (large ");
12697                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12698                    pw.print("), oom ");
12699                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12700                    pw.print(" kB");
12701                    pw.print(", restore limit ");
12702                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12703                    pw.print(" kB");
12704                    if (ActivityManager.isLowRamDeviceStatic()) {
12705                        pw.print(" (low-ram)");
12706                    }
12707                    if (ActivityManager.isHighEndGfx()) {
12708                        pw.print(" (high-end-gfx)");
12709                    }
12710                    pw.println();
12711                } else {
12712                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12713                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12714                    pw.println(voltile);
12715                    pw.print("tuning,");
12716                    pw.print(ActivityManager.staticGetMemoryClass());
12717                    pw.print(',');
12718                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12719                    pw.print(',');
12720                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12721                    if (ActivityManager.isLowRamDeviceStatic()) {
12722                        pw.print(",low-ram");
12723                    }
12724                    if (ActivityManager.isHighEndGfx()) {
12725                        pw.print(",high-end-gfx");
12726                    }
12727                    pw.println();
12728                }
12729            }
12730        }
12731    }
12732
12733    /**
12734     * Searches array of arguments for the specified string
12735     * @param args array of argument strings
12736     * @param value value to search for
12737     * @return true if the value is contained in the array
12738     */
12739    private static boolean scanArgs(String[] args, String value) {
12740        if (args != null) {
12741            for (String arg : args) {
12742                if (value.equals(arg)) {
12743                    return true;
12744                }
12745            }
12746        }
12747        return false;
12748    }
12749
12750    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12751            ContentProviderRecord cpr, boolean always) {
12752        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12753
12754        if (!inLaunching || always) {
12755            synchronized (cpr) {
12756                cpr.launchingApp = null;
12757                cpr.notifyAll();
12758            }
12759            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12760            String names[] = cpr.info.authority.split(";");
12761            for (int j = 0; j < names.length; j++) {
12762                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12763            }
12764        }
12765
12766        for (int i=0; i<cpr.connections.size(); i++) {
12767            ContentProviderConnection conn = cpr.connections.get(i);
12768            if (conn.waiting) {
12769                // If this connection is waiting for the provider, then we don't
12770                // need to mess with its process unless we are always removing
12771                // or for some reason the provider is not currently launching.
12772                if (inLaunching && !always) {
12773                    continue;
12774                }
12775            }
12776            ProcessRecord capp = conn.client;
12777            conn.dead = true;
12778            if (conn.stableCount > 0) {
12779                if (!capp.persistent && capp.thread != null
12780                        && capp.pid != 0
12781                        && capp.pid != MY_PID) {
12782                    killUnneededProcessLocked(capp, "depends on provider "
12783                            + cpr.name.flattenToShortString()
12784                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12785                }
12786            } else if (capp.thread != null && conn.provider.provider != null) {
12787                try {
12788                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12789                } catch (RemoteException e) {
12790                }
12791                // In the protocol here, we don't expect the client to correctly
12792                // clean up this connection, we'll just remove it.
12793                cpr.connections.remove(i);
12794                conn.client.conProviders.remove(conn);
12795            }
12796        }
12797
12798        if (inLaunching && always) {
12799            mLaunchingProviders.remove(cpr);
12800        }
12801        return inLaunching;
12802    }
12803
12804    /**
12805     * Main code for cleaning up a process when it has gone away.  This is
12806     * called both as a result of the process dying, or directly when stopping
12807     * a process when running in single process mode.
12808     */
12809    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12810            boolean restarting, boolean allowRestart, int index) {
12811        if (index >= 0) {
12812            removeLruProcessLocked(app);
12813            ProcessList.remove(app.pid);
12814        }
12815
12816        mProcessesToGc.remove(app);
12817        mPendingPssProcesses.remove(app);
12818
12819        // Dismiss any open dialogs.
12820        if (app.crashDialog != null && !app.forceCrashReport) {
12821            app.crashDialog.dismiss();
12822            app.crashDialog = null;
12823        }
12824        if (app.anrDialog != null) {
12825            app.anrDialog.dismiss();
12826            app.anrDialog = null;
12827        }
12828        if (app.waitDialog != null) {
12829            app.waitDialog.dismiss();
12830            app.waitDialog = null;
12831        }
12832
12833        app.crashing = false;
12834        app.notResponding = false;
12835
12836        app.resetPackageList(mProcessStats);
12837        app.unlinkDeathRecipient();
12838        app.makeInactive(mProcessStats);
12839        app.forcingToForeground = null;
12840        updateProcessForegroundLocked(app, false, false);
12841        app.foregroundActivities = false;
12842        app.hasShownUi = false;
12843        app.treatLikeActivity = false;
12844        app.hasAboveClient = false;
12845        app.hasClientActivities = false;
12846
12847        mServices.killServicesLocked(app, allowRestart);
12848
12849        boolean restart = false;
12850
12851        // Remove published content providers.
12852        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12853            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12854            final boolean always = app.bad || !allowRestart;
12855            if (removeDyingProviderLocked(app, cpr, always) || always) {
12856                // We left the provider in the launching list, need to
12857                // restart it.
12858                restart = true;
12859            }
12860
12861            cpr.provider = null;
12862            cpr.proc = null;
12863        }
12864        app.pubProviders.clear();
12865
12866        // Take care of any launching providers waiting for this process.
12867        if (checkAppInLaunchingProvidersLocked(app, false)) {
12868            restart = true;
12869        }
12870
12871        // Unregister from connected content providers.
12872        if (!app.conProviders.isEmpty()) {
12873            for (int i=0; i<app.conProviders.size(); i++) {
12874                ContentProviderConnection conn = app.conProviders.get(i);
12875                conn.provider.connections.remove(conn);
12876            }
12877            app.conProviders.clear();
12878        }
12879
12880        // At this point there may be remaining entries in mLaunchingProviders
12881        // where we were the only one waiting, so they are no longer of use.
12882        // Look for these and clean up if found.
12883        // XXX Commented out for now.  Trying to figure out a way to reproduce
12884        // the actual situation to identify what is actually going on.
12885        if (false) {
12886            for (int i=0; i<mLaunchingProviders.size(); i++) {
12887                ContentProviderRecord cpr = (ContentProviderRecord)
12888                        mLaunchingProviders.get(i);
12889                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12890                    synchronized (cpr) {
12891                        cpr.launchingApp = null;
12892                        cpr.notifyAll();
12893                    }
12894                }
12895            }
12896        }
12897
12898        skipCurrentReceiverLocked(app);
12899
12900        // Unregister any receivers.
12901        for (int i=app.receivers.size()-1; i>=0; i--) {
12902            removeReceiverLocked(app.receivers.valueAt(i));
12903        }
12904        app.receivers.clear();
12905
12906        // If the app is undergoing backup, tell the backup manager about it
12907        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12908            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12909                    + mBackupTarget.appInfo + " died during backup");
12910            try {
12911                IBackupManager bm = IBackupManager.Stub.asInterface(
12912                        ServiceManager.getService(Context.BACKUP_SERVICE));
12913                bm.agentDisconnected(app.info.packageName);
12914            } catch (RemoteException e) {
12915                // can't happen; backup manager is local
12916            }
12917        }
12918
12919        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12920            ProcessChangeItem item = mPendingProcessChanges.get(i);
12921            if (item.pid == app.pid) {
12922                mPendingProcessChanges.remove(i);
12923                mAvailProcessChanges.add(item);
12924            }
12925        }
12926        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12927
12928        // If the caller is restarting this app, then leave it in its
12929        // current lists and let the caller take care of it.
12930        if (restarting) {
12931            return;
12932        }
12933
12934        if (!app.persistent || app.isolated) {
12935            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12936                    "Removing non-persistent process during cleanup: " + app);
12937            mProcessNames.remove(app.processName, app.uid);
12938            mIsolatedProcesses.remove(app.uid);
12939            if (mHeavyWeightProcess == app) {
12940                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12941                        mHeavyWeightProcess.userId, 0));
12942                mHeavyWeightProcess = null;
12943            }
12944        } else if (!app.removed) {
12945            // This app is persistent, so we need to keep its record around.
12946            // If it is not already on the pending app list, add it there
12947            // and start a new process for it.
12948            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12949                mPersistentStartingProcesses.add(app);
12950                restart = true;
12951            }
12952        }
12953        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12954                "Clean-up removing on hold: " + app);
12955        mProcessesOnHold.remove(app);
12956
12957        if (app == mHomeProcess) {
12958            mHomeProcess = null;
12959        }
12960        if (app == mPreviousProcess) {
12961            mPreviousProcess = null;
12962        }
12963
12964        if (restart && !app.isolated) {
12965            // We have components that still need to be running in the
12966            // process, so re-launch it.
12967            mProcessNames.put(app.processName, app.uid, app);
12968            startProcessLocked(app, "restart", app.processName);
12969        } else if (app.pid > 0 && app.pid != MY_PID) {
12970            // Goodbye!
12971            boolean removed;
12972            synchronized (mPidsSelfLocked) {
12973                mPidsSelfLocked.remove(app.pid);
12974                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12975            }
12976            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12977                    app.processName, app.info.uid);
12978            if (app.isolated) {
12979                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12980            }
12981            app.setPid(0);
12982        }
12983    }
12984
12985    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12986        // Look through the content providers we are waiting to have launched,
12987        // and if any run in this process then either schedule a restart of
12988        // the process or kill the client waiting for it if this process has
12989        // gone bad.
12990        int NL = mLaunchingProviders.size();
12991        boolean restart = false;
12992        for (int i=0; i<NL; i++) {
12993            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12994            if (cpr.launchingApp == app) {
12995                if (!alwaysBad && !app.bad) {
12996                    restart = true;
12997                } else {
12998                    removeDyingProviderLocked(app, cpr, true);
12999                    // cpr should have been removed from mLaunchingProviders
13000                    NL = mLaunchingProviders.size();
13001                    i--;
13002                }
13003            }
13004        }
13005        return restart;
13006    }
13007
13008    // =========================================================
13009    // SERVICES
13010    // =========================================================
13011
13012    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13013            int flags) {
13014        enforceNotIsolatedCaller("getServices");
13015        synchronized (this) {
13016            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13017        }
13018    }
13019
13020    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13021        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13022        synchronized (this) {
13023            return mServices.getRunningServiceControlPanelLocked(name);
13024        }
13025    }
13026
13027    public ComponentName startService(IApplicationThread caller, Intent service,
13028            String resolvedType, int userId) {
13029        enforceNotIsolatedCaller("startService");
13030        // Refuse possible leaked file descriptors
13031        if (service != null && service.hasFileDescriptors() == true) {
13032            throw new IllegalArgumentException("File descriptors passed in Intent");
13033        }
13034
13035        if (DEBUG_SERVICE)
13036            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13037        synchronized(this) {
13038            final int callingPid = Binder.getCallingPid();
13039            final int callingUid = Binder.getCallingUid();
13040            final long origId = Binder.clearCallingIdentity();
13041            ComponentName res = mServices.startServiceLocked(caller, service,
13042                    resolvedType, callingPid, callingUid, userId);
13043            Binder.restoreCallingIdentity(origId);
13044            return res;
13045        }
13046    }
13047
13048    ComponentName startServiceInPackage(int uid,
13049            Intent service, String resolvedType, int userId) {
13050        synchronized(this) {
13051            if (DEBUG_SERVICE)
13052                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13053            final long origId = Binder.clearCallingIdentity();
13054            ComponentName res = mServices.startServiceLocked(null, service,
13055                    resolvedType, -1, uid, userId);
13056            Binder.restoreCallingIdentity(origId);
13057            return res;
13058        }
13059    }
13060
13061    public int stopService(IApplicationThread caller, Intent service,
13062            String resolvedType, int userId) {
13063        enforceNotIsolatedCaller("stopService");
13064        // Refuse possible leaked file descriptors
13065        if (service != null && service.hasFileDescriptors() == true) {
13066            throw new IllegalArgumentException("File descriptors passed in Intent");
13067        }
13068
13069        synchronized(this) {
13070            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13071        }
13072    }
13073
13074    public IBinder peekService(Intent service, String resolvedType) {
13075        enforceNotIsolatedCaller("peekService");
13076        // Refuse possible leaked file descriptors
13077        if (service != null && service.hasFileDescriptors() == true) {
13078            throw new IllegalArgumentException("File descriptors passed in Intent");
13079        }
13080        synchronized(this) {
13081            return mServices.peekServiceLocked(service, resolvedType);
13082        }
13083    }
13084
13085    public boolean stopServiceToken(ComponentName className, IBinder token,
13086            int startId) {
13087        synchronized(this) {
13088            return mServices.stopServiceTokenLocked(className, token, startId);
13089        }
13090    }
13091
13092    public void setServiceForeground(ComponentName className, IBinder token,
13093            int id, Notification notification, boolean removeNotification) {
13094        synchronized(this) {
13095            mServices.setServiceForegroundLocked(className, token, id, notification,
13096                    removeNotification);
13097        }
13098    }
13099
13100    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13101            boolean requireFull, String name, String callerPackage) {
13102        final int callingUserId = UserHandle.getUserId(callingUid);
13103        if (callingUserId != userId) {
13104            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13105                if ((requireFull || checkComponentPermission(
13106                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13107                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13108                        && checkComponentPermission(
13109                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13110                                callingPid, callingUid, -1, true)
13111                                != PackageManager.PERMISSION_GRANTED) {
13112                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13113                        // In this case, they would like to just execute as their
13114                        // owner user instead of failing.
13115                        userId = callingUserId;
13116                    } else {
13117                        StringBuilder builder = new StringBuilder(128);
13118                        builder.append("Permission Denial: ");
13119                        builder.append(name);
13120                        if (callerPackage != null) {
13121                            builder.append(" from ");
13122                            builder.append(callerPackage);
13123                        }
13124                        builder.append(" asks to run as user ");
13125                        builder.append(userId);
13126                        builder.append(" but is calling from user ");
13127                        builder.append(UserHandle.getUserId(callingUid));
13128                        builder.append("; this requires ");
13129                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13130                        if (!requireFull) {
13131                            builder.append(" or ");
13132                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13133                        }
13134                        String msg = builder.toString();
13135                        Slog.w(TAG, msg);
13136                        throw new SecurityException(msg);
13137                    }
13138                }
13139            }
13140            if (userId == UserHandle.USER_CURRENT
13141                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13142                // Note that we may be accessing this outside of a lock...
13143                // shouldn't be a big deal, if this is being called outside
13144                // of a locked context there is intrinsically a race with
13145                // the value the caller will receive and someone else changing it.
13146                userId = mCurrentUserId;
13147            }
13148            if (!allowAll && userId < 0) {
13149                throw new IllegalArgumentException(
13150                        "Call does not support special user #" + userId);
13151            }
13152        }
13153        return userId;
13154    }
13155
13156    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13157            String className, int flags) {
13158        boolean result = false;
13159        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13160            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13161                if (ActivityManager.checkUidPermission(
13162                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13163                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13164                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13165                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13166                            + " requests FLAG_SINGLE_USER, but app does not hold "
13167                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13168                    Slog.w(TAG, msg);
13169                    throw new SecurityException(msg);
13170                }
13171                result = true;
13172            }
13173        } else if (componentProcessName == aInfo.packageName) {
13174            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13175        } else if ("system".equals(componentProcessName)) {
13176            result = true;
13177        }
13178        if (DEBUG_MU) {
13179            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13180                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13181        }
13182        return result;
13183    }
13184
13185    public int bindService(IApplicationThread caller, IBinder token,
13186            Intent service, String resolvedType,
13187            IServiceConnection connection, int flags, int userId) {
13188        enforceNotIsolatedCaller("bindService");
13189        // Refuse possible leaked file descriptors
13190        if (service != null && service.hasFileDescriptors() == true) {
13191            throw new IllegalArgumentException("File descriptors passed in Intent");
13192        }
13193
13194        synchronized(this) {
13195            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13196                    connection, flags, userId);
13197        }
13198    }
13199
13200    public boolean unbindService(IServiceConnection connection) {
13201        synchronized (this) {
13202            return mServices.unbindServiceLocked(connection);
13203        }
13204    }
13205
13206    public void publishService(IBinder token, Intent intent, IBinder service) {
13207        // Refuse possible leaked file descriptors
13208        if (intent != null && intent.hasFileDescriptors() == true) {
13209            throw new IllegalArgumentException("File descriptors passed in Intent");
13210        }
13211
13212        synchronized(this) {
13213            if (!(token instanceof ServiceRecord)) {
13214                throw new IllegalArgumentException("Invalid service token");
13215            }
13216            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13217        }
13218    }
13219
13220    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13221        // Refuse possible leaked file descriptors
13222        if (intent != null && intent.hasFileDescriptors() == true) {
13223            throw new IllegalArgumentException("File descriptors passed in Intent");
13224        }
13225
13226        synchronized(this) {
13227            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13228        }
13229    }
13230
13231    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13232        synchronized(this) {
13233            if (!(token instanceof ServiceRecord)) {
13234                throw new IllegalArgumentException("Invalid service token");
13235            }
13236            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13237        }
13238    }
13239
13240    // =========================================================
13241    // BACKUP AND RESTORE
13242    // =========================================================
13243
13244    // Cause the target app to be launched if necessary and its backup agent
13245    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13246    // activity manager to announce its creation.
13247    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13248        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13249        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13250
13251        synchronized(this) {
13252            // !!! TODO: currently no check here that we're already bound
13253            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13254            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13255            synchronized (stats) {
13256                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13257            }
13258
13259            // Backup agent is now in use, its package can't be stopped.
13260            try {
13261                AppGlobals.getPackageManager().setPackageStoppedState(
13262                        app.packageName, false, UserHandle.getUserId(app.uid));
13263            } catch (RemoteException e) {
13264            } catch (IllegalArgumentException e) {
13265                Slog.w(TAG, "Failed trying to unstop package "
13266                        + app.packageName + ": " + e);
13267            }
13268
13269            BackupRecord r = new BackupRecord(ss, app, backupMode);
13270            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13271                    ? new ComponentName(app.packageName, app.backupAgentName)
13272                    : new ComponentName("android", "FullBackupAgent");
13273            // startProcessLocked() returns existing proc's record if it's already running
13274            ProcessRecord proc = startProcessLocked(app.processName, app,
13275                    false, 0, "backup", hostingName, false, false, false);
13276            if (proc == null) {
13277                Slog.e(TAG, "Unable to start backup agent process " + r);
13278                return false;
13279            }
13280
13281            r.app = proc;
13282            mBackupTarget = r;
13283            mBackupAppName = app.packageName;
13284
13285            // Try not to kill the process during backup
13286            updateOomAdjLocked(proc);
13287
13288            // If the process is already attached, schedule the creation of the backup agent now.
13289            // If it is not yet live, this will be done when it attaches to the framework.
13290            if (proc.thread != null) {
13291                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13292                try {
13293                    proc.thread.scheduleCreateBackupAgent(app,
13294                            compatibilityInfoForPackageLocked(app), backupMode);
13295                } catch (RemoteException e) {
13296                    // Will time out on the backup manager side
13297                }
13298            } else {
13299                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13300            }
13301            // Invariants: at this point, the target app process exists and the application
13302            // is either already running or in the process of coming up.  mBackupTarget and
13303            // mBackupAppName describe the app, so that when it binds back to the AM we
13304            // know that it's scheduled for a backup-agent operation.
13305        }
13306
13307        return true;
13308    }
13309
13310    @Override
13311    public void clearPendingBackup() {
13312        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13313        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13314
13315        synchronized (this) {
13316            mBackupTarget = null;
13317            mBackupAppName = null;
13318        }
13319    }
13320
13321    // A backup agent has just come up
13322    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13323        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13324                + " = " + agent);
13325
13326        synchronized(this) {
13327            if (!agentPackageName.equals(mBackupAppName)) {
13328                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13329                return;
13330            }
13331        }
13332
13333        long oldIdent = Binder.clearCallingIdentity();
13334        try {
13335            IBackupManager bm = IBackupManager.Stub.asInterface(
13336                    ServiceManager.getService(Context.BACKUP_SERVICE));
13337            bm.agentConnected(agentPackageName, agent);
13338        } catch (RemoteException e) {
13339            // can't happen; the backup manager service is local
13340        } catch (Exception e) {
13341            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13342            e.printStackTrace();
13343        } finally {
13344            Binder.restoreCallingIdentity(oldIdent);
13345        }
13346    }
13347
13348    // done with this agent
13349    public void unbindBackupAgent(ApplicationInfo appInfo) {
13350        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13351        if (appInfo == null) {
13352            Slog.w(TAG, "unbind backup agent for null app");
13353            return;
13354        }
13355
13356        synchronized(this) {
13357            try {
13358                if (mBackupAppName == null) {
13359                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13360                    return;
13361                }
13362
13363                if (!mBackupAppName.equals(appInfo.packageName)) {
13364                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13365                    return;
13366                }
13367
13368                // Not backing this app up any more; reset its OOM adjustment
13369                final ProcessRecord proc = mBackupTarget.app;
13370                updateOomAdjLocked(proc);
13371
13372                // If the app crashed during backup, 'thread' will be null here
13373                if (proc.thread != null) {
13374                    try {
13375                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13376                                compatibilityInfoForPackageLocked(appInfo));
13377                    } catch (Exception e) {
13378                        Slog.e(TAG, "Exception when unbinding backup agent:");
13379                        e.printStackTrace();
13380                    }
13381                }
13382            } finally {
13383                mBackupTarget = null;
13384                mBackupAppName = null;
13385            }
13386        }
13387    }
13388    // =========================================================
13389    // BROADCASTS
13390    // =========================================================
13391
13392    private final List getStickiesLocked(String action, IntentFilter filter,
13393            List cur, int userId) {
13394        final ContentResolver resolver = mContext.getContentResolver();
13395        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13396        if (stickies == null) {
13397            return cur;
13398        }
13399        final ArrayList<Intent> list = stickies.get(action);
13400        if (list == null) {
13401            return cur;
13402        }
13403        int N = list.size();
13404        for (int i=0; i<N; i++) {
13405            Intent intent = list.get(i);
13406            if (filter.match(resolver, intent, true, TAG) >= 0) {
13407                if (cur == null) {
13408                    cur = new ArrayList<Intent>();
13409                }
13410                cur.add(intent);
13411            }
13412        }
13413        return cur;
13414    }
13415
13416    boolean isPendingBroadcastProcessLocked(int pid) {
13417        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13418                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13419    }
13420
13421    void skipPendingBroadcastLocked(int pid) {
13422            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13423            for (BroadcastQueue queue : mBroadcastQueues) {
13424                queue.skipPendingBroadcastLocked(pid);
13425            }
13426    }
13427
13428    // The app just attached; send any pending broadcasts that it should receive
13429    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13430        boolean didSomething = false;
13431        for (BroadcastQueue queue : mBroadcastQueues) {
13432            didSomething |= queue.sendPendingBroadcastsLocked(app);
13433        }
13434        return didSomething;
13435    }
13436
13437    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13438            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13439        enforceNotIsolatedCaller("registerReceiver");
13440        int callingUid;
13441        int callingPid;
13442        synchronized(this) {
13443            ProcessRecord callerApp = null;
13444            if (caller != null) {
13445                callerApp = getRecordForAppLocked(caller);
13446                if (callerApp == null) {
13447                    throw new SecurityException(
13448                            "Unable to find app for caller " + caller
13449                            + " (pid=" + Binder.getCallingPid()
13450                            + ") when registering receiver " + receiver);
13451                }
13452                if (callerApp.info.uid != Process.SYSTEM_UID &&
13453                        !callerApp.pkgList.containsKey(callerPackage) &&
13454                        !"android".equals(callerPackage)) {
13455                    throw new SecurityException("Given caller package " + callerPackage
13456                            + " is not running in process " + callerApp);
13457                }
13458                callingUid = callerApp.info.uid;
13459                callingPid = callerApp.pid;
13460            } else {
13461                callerPackage = null;
13462                callingUid = Binder.getCallingUid();
13463                callingPid = Binder.getCallingPid();
13464            }
13465
13466            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13467                    true, true, "registerReceiver", callerPackage);
13468
13469            List allSticky = null;
13470
13471            // Look for any matching sticky broadcasts...
13472            Iterator actions = filter.actionsIterator();
13473            if (actions != null) {
13474                while (actions.hasNext()) {
13475                    String action = (String)actions.next();
13476                    allSticky = getStickiesLocked(action, filter, allSticky,
13477                            UserHandle.USER_ALL);
13478                    allSticky = getStickiesLocked(action, filter, allSticky,
13479                            UserHandle.getUserId(callingUid));
13480                }
13481            } else {
13482                allSticky = getStickiesLocked(null, filter, allSticky,
13483                        UserHandle.USER_ALL);
13484                allSticky = getStickiesLocked(null, filter, allSticky,
13485                        UserHandle.getUserId(callingUid));
13486            }
13487
13488            // The first sticky in the list is returned directly back to
13489            // the client.
13490            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13491
13492            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13493                    + ": " + sticky);
13494
13495            if (receiver == null) {
13496                return sticky;
13497            }
13498
13499            ReceiverList rl
13500                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13501            if (rl == null) {
13502                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13503                        userId, receiver);
13504                if (rl.app != null) {
13505                    rl.app.receivers.add(rl);
13506                } else {
13507                    try {
13508                        receiver.asBinder().linkToDeath(rl, 0);
13509                    } catch (RemoteException e) {
13510                        return sticky;
13511                    }
13512                    rl.linkedToDeath = true;
13513                }
13514                mRegisteredReceivers.put(receiver.asBinder(), rl);
13515            } else if (rl.uid != callingUid) {
13516                throw new IllegalArgumentException(
13517                        "Receiver requested to register for uid " + callingUid
13518                        + " was previously registered for uid " + rl.uid);
13519            } else if (rl.pid != callingPid) {
13520                throw new IllegalArgumentException(
13521                        "Receiver requested to register for pid " + callingPid
13522                        + " was previously registered for pid " + rl.pid);
13523            } else if (rl.userId != userId) {
13524                throw new IllegalArgumentException(
13525                        "Receiver requested to register for user " + userId
13526                        + " was previously registered for user " + rl.userId);
13527            }
13528            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13529                    permission, callingUid, userId);
13530            rl.add(bf);
13531            if (!bf.debugCheck()) {
13532                Slog.w(TAG, "==> For Dynamic broadast");
13533            }
13534            mReceiverResolver.addFilter(bf);
13535
13536            // Enqueue broadcasts for all existing stickies that match
13537            // this filter.
13538            if (allSticky != null) {
13539                ArrayList receivers = new ArrayList();
13540                receivers.add(bf);
13541
13542                int N = allSticky.size();
13543                for (int i=0; i<N; i++) {
13544                    Intent intent = (Intent)allSticky.get(i);
13545                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13546                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13547                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13548                            null, null, false, true, true, -1);
13549                    queue.enqueueParallelBroadcastLocked(r);
13550                    queue.scheduleBroadcastsLocked();
13551                }
13552            }
13553
13554            return sticky;
13555        }
13556    }
13557
13558    public void unregisterReceiver(IIntentReceiver receiver) {
13559        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13560
13561        final long origId = Binder.clearCallingIdentity();
13562        try {
13563            boolean doTrim = false;
13564
13565            synchronized(this) {
13566                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13567                if (rl != null) {
13568                    if (rl.curBroadcast != null) {
13569                        BroadcastRecord r = rl.curBroadcast;
13570                        final boolean doNext = finishReceiverLocked(
13571                                receiver.asBinder(), r.resultCode, r.resultData,
13572                                r.resultExtras, r.resultAbort);
13573                        if (doNext) {
13574                            doTrim = true;
13575                            r.queue.processNextBroadcast(false);
13576                        }
13577                    }
13578
13579                    if (rl.app != null) {
13580                        rl.app.receivers.remove(rl);
13581                    }
13582                    removeReceiverLocked(rl);
13583                    if (rl.linkedToDeath) {
13584                        rl.linkedToDeath = false;
13585                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13586                    }
13587                }
13588            }
13589
13590            // If we actually concluded any broadcasts, we might now be able
13591            // to trim the recipients' apps from our working set
13592            if (doTrim) {
13593                trimApplications();
13594                return;
13595            }
13596
13597        } finally {
13598            Binder.restoreCallingIdentity(origId);
13599        }
13600    }
13601
13602    void removeReceiverLocked(ReceiverList rl) {
13603        mRegisteredReceivers.remove(rl.receiver.asBinder());
13604        int N = rl.size();
13605        for (int i=0; i<N; i++) {
13606            mReceiverResolver.removeFilter(rl.get(i));
13607        }
13608    }
13609
13610    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13611        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13612            ProcessRecord r = mLruProcesses.get(i);
13613            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13614                try {
13615                    r.thread.dispatchPackageBroadcast(cmd, packages);
13616                } catch (RemoteException ex) {
13617                }
13618            }
13619        }
13620    }
13621
13622    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13623            int[] users) {
13624        List<ResolveInfo> receivers = null;
13625        try {
13626            HashSet<ComponentName> singleUserReceivers = null;
13627            boolean scannedFirstReceivers = false;
13628            for (int user : users) {
13629                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13630                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13631                if (user != 0 && newReceivers != null) {
13632                    // If this is not the primary user, we need to check for
13633                    // any receivers that should be filtered out.
13634                    for (int i=0; i<newReceivers.size(); i++) {
13635                        ResolveInfo ri = newReceivers.get(i);
13636                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13637                            newReceivers.remove(i);
13638                            i--;
13639                        }
13640                    }
13641                }
13642                if (newReceivers != null && newReceivers.size() == 0) {
13643                    newReceivers = null;
13644                }
13645                if (receivers == null) {
13646                    receivers = newReceivers;
13647                } else if (newReceivers != null) {
13648                    // We need to concatenate the additional receivers
13649                    // found with what we have do far.  This would be easy,
13650                    // but we also need to de-dup any receivers that are
13651                    // singleUser.
13652                    if (!scannedFirstReceivers) {
13653                        // Collect any single user receivers we had already retrieved.
13654                        scannedFirstReceivers = true;
13655                        for (int i=0; i<receivers.size(); i++) {
13656                            ResolveInfo ri = receivers.get(i);
13657                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13658                                ComponentName cn = new ComponentName(
13659                                        ri.activityInfo.packageName, ri.activityInfo.name);
13660                                if (singleUserReceivers == null) {
13661                                    singleUserReceivers = new HashSet<ComponentName>();
13662                                }
13663                                singleUserReceivers.add(cn);
13664                            }
13665                        }
13666                    }
13667                    // Add the new results to the existing results, tracking
13668                    // and de-dupping single user receivers.
13669                    for (int i=0; i<newReceivers.size(); i++) {
13670                        ResolveInfo ri = newReceivers.get(i);
13671                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13672                            ComponentName cn = new ComponentName(
13673                                    ri.activityInfo.packageName, ri.activityInfo.name);
13674                            if (singleUserReceivers == null) {
13675                                singleUserReceivers = new HashSet<ComponentName>();
13676                            }
13677                            if (!singleUserReceivers.contains(cn)) {
13678                                singleUserReceivers.add(cn);
13679                                receivers.add(ri);
13680                            }
13681                        } else {
13682                            receivers.add(ri);
13683                        }
13684                    }
13685                }
13686            }
13687        } catch (RemoteException ex) {
13688            // pm is in same process, this will never happen.
13689        }
13690        return receivers;
13691    }
13692
13693    private final int broadcastIntentLocked(ProcessRecord callerApp,
13694            String callerPackage, Intent intent, String resolvedType,
13695            IIntentReceiver resultTo, int resultCode, String resultData,
13696            Bundle map, String requiredPermission, int appOp,
13697            boolean ordered, boolean sticky, int callingPid, int callingUid,
13698            int userId) {
13699        intent = new Intent(intent);
13700
13701        // By default broadcasts do not go to stopped apps.
13702        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13703
13704        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13705            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13706            + " ordered=" + ordered + " userid=" + userId);
13707        if ((resultTo != null) && !ordered) {
13708            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13709        }
13710
13711        userId = handleIncomingUser(callingPid, callingUid, userId,
13712                true, false, "broadcast", callerPackage);
13713
13714        // Make sure that the user who is receiving this broadcast is started.
13715        // If not, we will just skip it.
13716        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13717            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13718                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13719                Slog.w(TAG, "Skipping broadcast of " + intent
13720                        + ": user " + userId + " is stopped");
13721                return ActivityManager.BROADCAST_SUCCESS;
13722            }
13723        }
13724
13725        /*
13726         * Prevent non-system code (defined here to be non-persistent
13727         * processes) from sending protected broadcasts.
13728         */
13729        int callingAppId = UserHandle.getAppId(callingUid);
13730        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13731            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13732            callingUid == 0) {
13733            // Always okay.
13734        } else if (callerApp == null || !callerApp.persistent) {
13735            try {
13736                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13737                        intent.getAction())) {
13738                    String msg = "Permission Denial: not allowed to send broadcast "
13739                            + intent.getAction() + " from pid="
13740                            + callingPid + ", uid=" + callingUid;
13741                    Slog.w(TAG, msg);
13742                    throw new SecurityException(msg);
13743                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13744                    // Special case for compatibility: we don't want apps to send this,
13745                    // but historically it has not been protected and apps may be using it
13746                    // to poke their own app widget.  So, instead of making it protected,
13747                    // just limit it to the caller.
13748                    if (callerApp == null) {
13749                        String msg = "Permission Denial: not allowed to send broadcast "
13750                                + intent.getAction() + " from unknown caller.";
13751                        Slog.w(TAG, msg);
13752                        throw new SecurityException(msg);
13753                    } else if (intent.getComponent() != null) {
13754                        // They are good enough to send to an explicit component...  verify
13755                        // it is being sent to the calling app.
13756                        if (!intent.getComponent().getPackageName().equals(
13757                                callerApp.info.packageName)) {
13758                            String msg = "Permission Denial: not allowed to send broadcast "
13759                                    + intent.getAction() + " to "
13760                                    + intent.getComponent().getPackageName() + " from "
13761                                    + callerApp.info.packageName;
13762                            Slog.w(TAG, msg);
13763                            throw new SecurityException(msg);
13764                        }
13765                    } else {
13766                        // Limit broadcast to their own package.
13767                        intent.setPackage(callerApp.info.packageName);
13768                    }
13769                }
13770            } catch (RemoteException e) {
13771                Slog.w(TAG, "Remote exception", e);
13772                return ActivityManager.BROADCAST_SUCCESS;
13773            }
13774        }
13775
13776        // Handle special intents: if this broadcast is from the package
13777        // manager about a package being removed, we need to remove all of
13778        // its activities from the history stack.
13779        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13780                intent.getAction());
13781        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13782                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13783                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13784                || uidRemoved) {
13785            if (checkComponentPermission(
13786                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13787                    callingPid, callingUid, -1, true)
13788                    == PackageManager.PERMISSION_GRANTED) {
13789                if (uidRemoved) {
13790                    final Bundle intentExtras = intent.getExtras();
13791                    final int uid = intentExtras != null
13792                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13793                    if (uid >= 0) {
13794                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13795                        synchronized (bs) {
13796                            bs.removeUidStatsLocked(uid);
13797                        }
13798                        mAppOpsService.uidRemoved(uid);
13799                    }
13800                } else {
13801                    // If resources are unavailable just force stop all
13802                    // those packages and flush the attribute cache as well.
13803                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13804                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13805                        if (list != null && (list.length > 0)) {
13806                            for (String pkg : list) {
13807                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13808                                        "storage unmount");
13809                            }
13810                            sendPackageBroadcastLocked(
13811                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13812                        }
13813                    } else {
13814                        Uri data = intent.getData();
13815                        String ssp;
13816                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13817                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13818                                    intent.getAction());
13819                            boolean fullUninstall = removed &&
13820                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13821                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13822                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13823                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13824                                        false, fullUninstall, userId,
13825                                        removed ? "pkg removed" : "pkg changed");
13826                            }
13827                            if (removed) {
13828                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13829                                        new String[] {ssp}, userId);
13830                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13831                                    mAppOpsService.packageRemoved(
13832                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13833
13834                                    // Remove all permissions granted from/to this package
13835                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13836                                }
13837                            }
13838                        }
13839                    }
13840                }
13841            } else {
13842                String msg = "Permission Denial: " + intent.getAction()
13843                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13844                        + ", uid=" + callingUid + ")"
13845                        + " requires "
13846                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13847                Slog.w(TAG, msg);
13848                throw new SecurityException(msg);
13849            }
13850
13851        // Special case for adding a package: by default turn on compatibility
13852        // mode.
13853        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13854            Uri data = intent.getData();
13855            String ssp;
13856            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13857                mCompatModePackages.handlePackageAddedLocked(ssp,
13858                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13859            }
13860        }
13861
13862        /*
13863         * If this is the time zone changed action, queue up a message that will reset the timezone
13864         * of all currently running processes. This message will get queued up before the broadcast
13865         * happens.
13866         */
13867        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13868            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13869        }
13870
13871        /*
13872         * If the user set the time, let all running processes know.
13873         */
13874        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13875            final int is24Hour = intent.getBooleanExtra(
13876                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13877            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13878        }
13879
13880        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13881            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13882        }
13883
13884        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13885            ProxyInfo proxy = intent.getParcelableExtra("proxy");
13886            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13887        }
13888
13889        // Add to the sticky list if requested.
13890        if (sticky) {
13891            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13892                    callingPid, callingUid)
13893                    != PackageManager.PERMISSION_GRANTED) {
13894                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13895                        + callingPid + ", uid=" + callingUid
13896                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13897                Slog.w(TAG, msg);
13898                throw new SecurityException(msg);
13899            }
13900            if (requiredPermission != null) {
13901                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13902                        + " and enforce permission " + requiredPermission);
13903                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13904            }
13905            if (intent.getComponent() != null) {
13906                throw new SecurityException(
13907                        "Sticky broadcasts can't target a specific component");
13908            }
13909            // We use userId directly here, since the "all" target is maintained
13910            // as a separate set of sticky broadcasts.
13911            if (userId != UserHandle.USER_ALL) {
13912                // But first, if this is not a broadcast to all users, then
13913                // make sure it doesn't conflict with an existing broadcast to
13914                // all users.
13915                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13916                        UserHandle.USER_ALL);
13917                if (stickies != null) {
13918                    ArrayList<Intent> list = stickies.get(intent.getAction());
13919                    if (list != null) {
13920                        int N = list.size();
13921                        int i;
13922                        for (i=0; i<N; i++) {
13923                            if (intent.filterEquals(list.get(i))) {
13924                                throw new IllegalArgumentException(
13925                                        "Sticky broadcast " + intent + " for user "
13926                                        + userId + " conflicts with existing global broadcast");
13927                            }
13928                        }
13929                    }
13930                }
13931            }
13932            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13933            if (stickies == null) {
13934                stickies = new ArrayMap<String, ArrayList<Intent>>();
13935                mStickyBroadcasts.put(userId, stickies);
13936            }
13937            ArrayList<Intent> list = stickies.get(intent.getAction());
13938            if (list == null) {
13939                list = new ArrayList<Intent>();
13940                stickies.put(intent.getAction(), list);
13941            }
13942            int N = list.size();
13943            int i;
13944            for (i=0; i<N; i++) {
13945                if (intent.filterEquals(list.get(i))) {
13946                    // This sticky already exists, replace it.
13947                    list.set(i, new Intent(intent));
13948                    break;
13949                }
13950            }
13951            if (i >= N) {
13952                list.add(new Intent(intent));
13953            }
13954        }
13955
13956        int[] users;
13957        if (userId == UserHandle.USER_ALL) {
13958            // Caller wants broadcast to go to all started users.
13959            users = mStartedUserArray;
13960        } else {
13961            // Caller wants broadcast to go to one specific user.
13962            users = new int[] {userId};
13963        }
13964
13965        // Figure out who all will receive this broadcast.
13966        List receivers = null;
13967        List<BroadcastFilter> registeredReceivers = null;
13968        // Need to resolve the intent to interested receivers...
13969        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13970                 == 0) {
13971            receivers = collectReceiverComponents(intent, resolvedType, users);
13972        }
13973        if (intent.getComponent() == null) {
13974            registeredReceivers = mReceiverResolver.queryIntent(intent,
13975                    resolvedType, false, userId);
13976        }
13977
13978        final boolean replacePending =
13979                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13980
13981        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13982                + " replacePending=" + replacePending);
13983
13984        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13985        if (!ordered && NR > 0) {
13986            // If we are not serializing this broadcast, then send the
13987            // registered receivers separately so they don't wait for the
13988            // components to be launched.
13989            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13990            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13991                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13992                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13993                    ordered, sticky, false, userId);
13994            if (DEBUG_BROADCAST) Slog.v(
13995                    TAG, "Enqueueing parallel broadcast " + r);
13996            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13997            if (!replaced) {
13998                queue.enqueueParallelBroadcastLocked(r);
13999                queue.scheduleBroadcastsLocked();
14000            }
14001            registeredReceivers = null;
14002            NR = 0;
14003        }
14004
14005        // Merge into one list.
14006        int ir = 0;
14007        if (receivers != null) {
14008            // A special case for PACKAGE_ADDED: do not allow the package
14009            // being added to see this broadcast.  This prevents them from
14010            // using this as a back door to get run as soon as they are
14011            // installed.  Maybe in the future we want to have a special install
14012            // broadcast or such for apps, but we'd like to deliberately make
14013            // this decision.
14014            String skipPackages[] = null;
14015            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14016                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14017                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14018                Uri data = intent.getData();
14019                if (data != null) {
14020                    String pkgName = data.getSchemeSpecificPart();
14021                    if (pkgName != null) {
14022                        skipPackages = new String[] { pkgName };
14023                    }
14024                }
14025            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14026                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14027            }
14028            if (skipPackages != null && (skipPackages.length > 0)) {
14029                for (String skipPackage : skipPackages) {
14030                    if (skipPackage != null) {
14031                        int NT = receivers.size();
14032                        for (int it=0; it<NT; it++) {
14033                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14034                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14035                                receivers.remove(it);
14036                                it--;
14037                                NT--;
14038                            }
14039                        }
14040                    }
14041                }
14042            }
14043
14044            int NT = receivers != null ? receivers.size() : 0;
14045            int it = 0;
14046            ResolveInfo curt = null;
14047            BroadcastFilter curr = null;
14048            while (it < NT && ir < NR) {
14049                if (curt == null) {
14050                    curt = (ResolveInfo)receivers.get(it);
14051                }
14052                if (curr == null) {
14053                    curr = registeredReceivers.get(ir);
14054                }
14055                if (curr.getPriority() >= curt.priority) {
14056                    // Insert this broadcast record into the final list.
14057                    receivers.add(it, curr);
14058                    ir++;
14059                    curr = null;
14060                    it++;
14061                    NT++;
14062                } else {
14063                    // Skip to the next ResolveInfo in the final list.
14064                    it++;
14065                    curt = null;
14066                }
14067            }
14068        }
14069        while (ir < NR) {
14070            if (receivers == null) {
14071                receivers = new ArrayList();
14072            }
14073            receivers.add(registeredReceivers.get(ir));
14074            ir++;
14075        }
14076
14077        if ((receivers != null && receivers.size() > 0)
14078                || resultTo != null) {
14079            BroadcastQueue queue = broadcastQueueForIntent(intent);
14080            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14081                    callerPackage, callingPid, callingUid, resolvedType,
14082                    requiredPermission, appOp, receivers, resultTo, resultCode,
14083                    resultData, map, ordered, sticky, false, userId);
14084            if (DEBUG_BROADCAST) Slog.v(
14085                    TAG, "Enqueueing ordered broadcast " + r
14086                    + ": prev had " + queue.mOrderedBroadcasts.size());
14087            if (DEBUG_BROADCAST) {
14088                int seq = r.intent.getIntExtra("seq", -1);
14089                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14090            }
14091            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14092            if (!replaced) {
14093                queue.enqueueOrderedBroadcastLocked(r);
14094                queue.scheduleBroadcastsLocked();
14095            }
14096        }
14097
14098        return ActivityManager.BROADCAST_SUCCESS;
14099    }
14100
14101    final Intent verifyBroadcastLocked(Intent intent) {
14102        // Refuse possible leaked file descriptors
14103        if (intent != null && intent.hasFileDescriptors() == true) {
14104            throw new IllegalArgumentException("File descriptors passed in Intent");
14105        }
14106
14107        int flags = intent.getFlags();
14108
14109        if (!mProcessesReady) {
14110            // if the caller really truly claims to know what they're doing, go
14111            // ahead and allow the broadcast without launching any receivers
14112            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14113                intent = new Intent(intent);
14114                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14115            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14116                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14117                        + " before boot completion");
14118                throw new IllegalStateException("Cannot broadcast before boot completed");
14119            }
14120        }
14121
14122        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14123            throw new IllegalArgumentException(
14124                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14125        }
14126
14127        return intent;
14128    }
14129
14130    public final int broadcastIntent(IApplicationThread caller,
14131            Intent intent, String resolvedType, IIntentReceiver resultTo,
14132            int resultCode, String resultData, Bundle map,
14133            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14134        enforceNotIsolatedCaller("broadcastIntent");
14135        synchronized(this) {
14136            intent = verifyBroadcastLocked(intent);
14137
14138            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14139            final int callingPid = Binder.getCallingPid();
14140            final int callingUid = Binder.getCallingUid();
14141            final long origId = Binder.clearCallingIdentity();
14142            int res = broadcastIntentLocked(callerApp,
14143                    callerApp != null ? callerApp.info.packageName : null,
14144                    intent, resolvedType, resultTo,
14145                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14146                    callingPid, callingUid, userId);
14147            Binder.restoreCallingIdentity(origId);
14148            return res;
14149        }
14150    }
14151
14152    int broadcastIntentInPackage(String packageName, int uid,
14153            Intent intent, String resolvedType, IIntentReceiver resultTo,
14154            int resultCode, String resultData, Bundle map,
14155            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14156        synchronized(this) {
14157            intent = verifyBroadcastLocked(intent);
14158
14159            final long origId = Binder.clearCallingIdentity();
14160            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14161                    resultTo, resultCode, resultData, map, requiredPermission,
14162                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14163            Binder.restoreCallingIdentity(origId);
14164            return res;
14165        }
14166    }
14167
14168    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14169        // Refuse possible leaked file descriptors
14170        if (intent != null && intent.hasFileDescriptors() == true) {
14171            throw new IllegalArgumentException("File descriptors passed in Intent");
14172        }
14173
14174        userId = handleIncomingUser(Binder.getCallingPid(),
14175                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14176
14177        synchronized(this) {
14178            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14179                    != PackageManager.PERMISSION_GRANTED) {
14180                String msg = "Permission Denial: unbroadcastIntent() from pid="
14181                        + Binder.getCallingPid()
14182                        + ", uid=" + Binder.getCallingUid()
14183                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14184                Slog.w(TAG, msg);
14185                throw new SecurityException(msg);
14186            }
14187            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14188            if (stickies != null) {
14189                ArrayList<Intent> list = stickies.get(intent.getAction());
14190                if (list != null) {
14191                    int N = list.size();
14192                    int i;
14193                    for (i=0; i<N; i++) {
14194                        if (intent.filterEquals(list.get(i))) {
14195                            list.remove(i);
14196                            break;
14197                        }
14198                    }
14199                    if (list.size() <= 0) {
14200                        stickies.remove(intent.getAction());
14201                    }
14202                }
14203                if (stickies.size() <= 0) {
14204                    mStickyBroadcasts.remove(userId);
14205                }
14206            }
14207        }
14208    }
14209
14210    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14211            String resultData, Bundle resultExtras, boolean resultAbort) {
14212        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14213        if (r == null) {
14214            Slog.w(TAG, "finishReceiver called but not found on queue");
14215            return false;
14216        }
14217
14218        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14219    }
14220
14221    void backgroundServicesFinishedLocked(int userId) {
14222        for (BroadcastQueue queue : mBroadcastQueues) {
14223            queue.backgroundServicesFinishedLocked(userId);
14224        }
14225    }
14226
14227    public void finishReceiver(IBinder who, int resultCode, String resultData,
14228            Bundle resultExtras, boolean resultAbort) {
14229        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14230
14231        // Refuse possible leaked file descriptors
14232        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14233            throw new IllegalArgumentException("File descriptors passed in Bundle");
14234        }
14235
14236        final long origId = Binder.clearCallingIdentity();
14237        try {
14238            boolean doNext = false;
14239            BroadcastRecord r;
14240
14241            synchronized(this) {
14242                r = broadcastRecordForReceiverLocked(who);
14243                if (r != null) {
14244                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14245                        resultData, resultExtras, resultAbort, true);
14246                }
14247            }
14248
14249            if (doNext) {
14250                r.queue.processNextBroadcast(false);
14251            }
14252            trimApplications();
14253        } finally {
14254            Binder.restoreCallingIdentity(origId);
14255        }
14256    }
14257
14258    // =========================================================
14259    // INSTRUMENTATION
14260    // =========================================================
14261
14262    public boolean startInstrumentation(ComponentName className,
14263            String profileFile, int flags, Bundle arguments,
14264            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14265            int userId) {
14266        enforceNotIsolatedCaller("startInstrumentation");
14267        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14268                userId, false, true, "startInstrumentation", null);
14269        // Refuse possible leaked file descriptors
14270        if (arguments != null && arguments.hasFileDescriptors()) {
14271            throw new IllegalArgumentException("File descriptors passed in Bundle");
14272        }
14273
14274        synchronized(this) {
14275            InstrumentationInfo ii = null;
14276            ApplicationInfo ai = null;
14277            try {
14278                ii = mContext.getPackageManager().getInstrumentationInfo(
14279                    className, STOCK_PM_FLAGS);
14280                ai = AppGlobals.getPackageManager().getApplicationInfo(
14281                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14282            } catch (PackageManager.NameNotFoundException e) {
14283            } catch (RemoteException e) {
14284            }
14285            if (ii == null) {
14286                reportStartInstrumentationFailure(watcher, className,
14287                        "Unable to find instrumentation info for: " + className);
14288                return false;
14289            }
14290            if (ai == null) {
14291                reportStartInstrumentationFailure(watcher, className,
14292                        "Unable to find instrumentation target package: " + ii.targetPackage);
14293                return false;
14294            }
14295
14296            int match = mContext.getPackageManager().checkSignatures(
14297                    ii.targetPackage, ii.packageName);
14298            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14299                String msg = "Permission Denial: starting instrumentation "
14300                        + className + " from pid="
14301                        + Binder.getCallingPid()
14302                        + ", uid=" + Binder.getCallingPid()
14303                        + " not allowed because package " + ii.packageName
14304                        + " does not have a signature matching the target "
14305                        + ii.targetPackage;
14306                reportStartInstrumentationFailure(watcher, className, msg);
14307                throw new SecurityException(msg);
14308            }
14309
14310            final long origId = Binder.clearCallingIdentity();
14311            // Instrumentation can kill and relaunch even persistent processes
14312            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14313                    "start instr");
14314            ProcessRecord app = addAppLocked(ai, false);
14315            app.instrumentationClass = className;
14316            app.instrumentationInfo = ai;
14317            app.instrumentationProfileFile = profileFile;
14318            app.instrumentationArguments = arguments;
14319            app.instrumentationWatcher = watcher;
14320            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14321            app.instrumentationResultClass = className;
14322            Binder.restoreCallingIdentity(origId);
14323        }
14324
14325        return true;
14326    }
14327
14328    /**
14329     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14330     * error to the logs, but if somebody is watching, send the report there too.  This enables
14331     * the "am" command to report errors with more information.
14332     *
14333     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14334     * @param cn The component name of the instrumentation.
14335     * @param report The error report.
14336     */
14337    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14338            ComponentName cn, String report) {
14339        Slog.w(TAG, report);
14340        try {
14341            if (watcher != null) {
14342                Bundle results = new Bundle();
14343                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14344                results.putString("Error", report);
14345                watcher.instrumentationStatus(cn, -1, results);
14346            }
14347        } catch (RemoteException e) {
14348            Slog.w(TAG, e);
14349        }
14350    }
14351
14352    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14353        if (app.instrumentationWatcher != null) {
14354            try {
14355                // NOTE:  IInstrumentationWatcher *must* be oneway here
14356                app.instrumentationWatcher.instrumentationFinished(
14357                    app.instrumentationClass,
14358                    resultCode,
14359                    results);
14360            } catch (RemoteException e) {
14361            }
14362        }
14363        if (app.instrumentationUiAutomationConnection != null) {
14364            try {
14365                app.instrumentationUiAutomationConnection.shutdown();
14366            } catch (RemoteException re) {
14367                /* ignore */
14368            }
14369            // Only a UiAutomation can set this flag and now that
14370            // it is finished we make sure it is reset to its default.
14371            mUserIsMonkey = false;
14372        }
14373        app.instrumentationWatcher = null;
14374        app.instrumentationUiAutomationConnection = null;
14375        app.instrumentationClass = null;
14376        app.instrumentationInfo = null;
14377        app.instrumentationProfileFile = null;
14378        app.instrumentationArguments = null;
14379
14380        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14381                "finished inst");
14382    }
14383
14384    public void finishInstrumentation(IApplicationThread target,
14385            int resultCode, Bundle results) {
14386        int userId = UserHandle.getCallingUserId();
14387        // Refuse possible leaked file descriptors
14388        if (results != null && results.hasFileDescriptors()) {
14389            throw new IllegalArgumentException("File descriptors passed in Intent");
14390        }
14391
14392        synchronized(this) {
14393            ProcessRecord app = getRecordForAppLocked(target);
14394            if (app == null) {
14395                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14396                return;
14397            }
14398            final long origId = Binder.clearCallingIdentity();
14399            finishInstrumentationLocked(app, resultCode, results);
14400            Binder.restoreCallingIdentity(origId);
14401        }
14402    }
14403
14404    // =========================================================
14405    // CONFIGURATION
14406    // =========================================================
14407
14408    public ConfigurationInfo getDeviceConfigurationInfo() {
14409        ConfigurationInfo config = new ConfigurationInfo();
14410        synchronized (this) {
14411            config.reqTouchScreen = mConfiguration.touchscreen;
14412            config.reqKeyboardType = mConfiguration.keyboard;
14413            config.reqNavigation = mConfiguration.navigation;
14414            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14415                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14416                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14417            }
14418            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14419                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14420                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14421            }
14422            config.reqGlEsVersion = GL_ES_VERSION;
14423        }
14424        return config;
14425    }
14426
14427    ActivityStack getFocusedStack() {
14428        return mStackSupervisor.getFocusedStack();
14429    }
14430
14431    public Configuration getConfiguration() {
14432        Configuration ci;
14433        synchronized(this) {
14434            ci = new Configuration(mConfiguration);
14435        }
14436        return ci;
14437    }
14438
14439    public void updatePersistentConfiguration(Configuration values) {
14440        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14441                "updateConfiguration()");
14442        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14443                "updateConfiguration()");
14444        if (values == null) {
14445            throw new NullPointerException("Configuration must not be null");
14446        }
14447
14448        synchronized(this) {
14449            final long origId = Binder.clearCallingIdentity();
14450            updateConfigurationLocked(values, null, true, false);
14451            Binder.restoreCallingIdentity(origId);
14452        }
14453    }
14454
14455    public void updateConfiguration(Configuration values) {
14456        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14457                "updateConfiguration()");
14458
14459        synchronized(this) {
14460            if (values == null && mWindowManager != null) {
14461                // sentinel: fetch the current configuration from the window manager
14462                values = mWindowManager.computeNewConfiguration();
14463            }
14464
14465            if (mWindowManager != null) {
14466                mProcessList.applyDisplaySize(mWindowManager);
14467            }
14468
14469            final long origId = Binder.clearCallingIdentity();
14470            if (values != null) {
14471                Settings.System.clearConfiguration(values);
14472            }
14473            updateConfigurationLocked(values, null, false, false);
14474            Binder.restoreCallingIdentity(origId);
14475        }
14476    }
14477
14478    /**
14479     * Do either or both things: (1) change the current configuration, and (2)
14480     * make sure the given activity is running with the (now) current
14481     * configuration.  Returns true if the activity has been left running, or
14482     * false if <var>starting</var> is being destroyed to match the new
14483     * configuration.
14484     * @param persistent TODO
14485     */
14486    boolean updateConfigurationLocked(Configuration values,
14487            ActivityRecord starting, boolean persistent, boolean initLocale) {
14488        int changes = 0;
14489
14490        if (values != null) {
14491            Configuration newConfig = new Configuration(mConfiguration);
14492            changes = newConfig.updateFrom(values);
14493            if (changes != 0) {
14494                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14495                    Slog.i(TAG, "Updating configuration to: " + values);
14496                }
14497
14498                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14499
14500                if (values.locale != null && !initLocale) {
14501                    saveLocaleLocked(values.locale,
14502                                     !values.locale.equals(mConfiguration.locale),
14503                                     values.userSetLocale);
14504                }
14505
14506                mConfigurationSeq++;
14507                if (mConfigurationSeq <= 0) {
14508                    mConfigurationSeq = 1;
14509                }
14510                newConfig.seq = mConfigurationSeq;
14511                mConfiguration = newConfig;
14512                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14513                mUsageStatsService.noteStartConfig(newConfig);
14514
14515                final Configuration configCopy = new Configuration(mConfiguration);
14516
14517                // TODO: If our config changes, should we auto dismiss any currently
14518                // showing dialogs?
14519                mShowDialogs = shouldShowDialogs(newConfig);
14520
14521                AttributeCache ac = AttributeCache.instance();
14522                if (ac != null) {
14523                    ac.updateConfiguration(configCopy);
14524                }
14525
14526                // Make sure all resources in our process are updated
14527                // right now, so that anyone who is going to retrieve
14528                // resource values after we return will be sure to get
14529                // the new ones.  This is especially important during
14530                // boot, where the first config change needs to guarantee
14531                // all resources have that config before following boot
14532                // code is executed.
14533                mSystemThread.applyConfigurationToResources(configCopy);
14534
14535                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14536                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14537                    msg.obj = new Configuration(configCopy);
14538                    mHandler.sendMessage(msg);
14539                }
14540
14541                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14542                    ProcessRecord app = mLruProcesses.get(i);
14543                    try {
14544                        if (app.thread != null) {
14545                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14546                                    + app.processName + " new config " + mConfiguration);
14547                            app.thread.scheduleConfigurationChanged(configCopy);
14548                        }
14549                    } catch (Exception e) {
14550                    }
14551                }
14552                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14553                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14554                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14555                        | Intent.FLAG_RECEIVER_FOREGROUND);
14556                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14557                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14558                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14559                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14560                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14561                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14562                    broadcastIntentLocked(null, null, intent,
14563                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14564                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14565                }
14566            }
14567        }
14568
14569        boolean kept = true;
14570        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14571        // mainStack is null during startup.
14572        if (mainStack != null) {
14573            if (changes != 0 && starting == null) {
14574                // If the configuration changed, and the caller is not already
14575                // in the process of starting an activity, then find the top
14576                // activity to check if its configuration needs to change.
14577                starting = mainStack.topRunningActivityLocked(null);
14578            }
14579
14580            if (starting != null) {
14581                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14582                // And we need to make sure at this point that all other activities
14583                // are made visible with the correct configuration.
14584                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14585            }
14586        }
14587
14588        if (values != null && mWindowManager != null) {
14589            mWindowManager.setNewConfiguration(mConfiguration);
14590        }
14591
14592        return kept;
14593    }
14594
14595    /**
14596     * Decide based on the configuration whether we should shouw the ANR,
14597     * crash, etc dialogs.  The idea is that if there is no affordnace to
14598     * press the on-screen buttons, we shouldn't show the dialog.
14599     *
14600     * A thought: SystemUI might also want to get told about this, the Power
14601     * dialog / global actions also might want different behaviors.
14602     */
14603    private static final boolean shouldShowDialogs(Configuration config) {
14604        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14605                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14606    }
14607
14608    /**
14609     * Save the locale.  You must be inside a synchronized (this) block.
14610     */
14611    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14612        if(isDiff) {
14613            SystemProperties.set("user.language", l.getLanguage());
14614            SystemProperties.set("user.region", l.getCountry());
14615        }
14616
14617        if(isPersist) {
14618            SystemProperties.set("persist.sys.language", l.getLanguage());
14619            SystemProperties.set("persist.sys.country", l.getCountry());
14620            SystemProperties.set("persist.sys.localevar", l.getVariant());
14621        }
14622    }
14623
14624    @Override
14625    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14626        ActivityRecord srec = ActivityRecord.forToken(token);
14627        return srec != null && srec.task.affinity != null &&
14628                srec.task.affinity.equals(destAffinity);
14629    }
14630
14631    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14632            Intent resultData) {
14633
14634        synchronized (this) {
14635            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14636            if (stack != null) {
14637                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14638            }
14639            return false;
14640        }
14641    }
14642
14643    public int getLaunchedFromUid(IBinder activityToken) {
14644        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14645        if (srec == null) {
14646            return -1;
14647        }
14648        return srec.launchedFromUid;
14649    }
14650
14651    public String getLaunchedFromPackage(IBinder activityToken) {
14652        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14653        if (srec == null) {
14654            return null;
14655        }
14656        return srec.launchedFromPackage;
14657    }
14658
14659    // =========================================================
14660    // LIFETIME MANAGEMENT
14661    // =========================================================
14662
14663    // Returns which broadcast queue the app is the current [or imminent] receiver
14664    // on, or 'null' if the app is not an active broadcast recipient.
14665    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14666        BroadcastRecord r = app.curReceiver;
14667        if (r != null) {
14668            return r.queue;
14669        }
14670
14671        // It's not the current receiver, but it might be starting up to become one
14672        synchronized (this) {
14673            for (BroadcastQueue queue : mBroadcastQueues) {
14674                r = queue.mPendingBroadcast;
14675                if (r != null && r.curApp == app) {
14676                    // found it; report which queue it's in
14677                    return queue;
14678                }
14679            }
14680        }
14681
14682        return null;
14683    }
14684
14685    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14686            boolean doingAll, long now) {
14687        if (mAdjSeq == app.adjSeq) {
14688            // This adjustment has already been computed.
14689            return app.curRawAdj;
14690        }
14691
14692        if (app.thread == null) {
14693            app.adjSeq = mAdjSeq;
14694            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14695            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14696            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14697        }
14698
14699        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14700        app.adjSource = null;
14701        app.adjTarget = null;
14702        app.empty = false;
14703        app.cached = false;
14704
14705        final int activitiesSize = app.activities.size();
14706
14707        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14708            // The max adjustment doesn't allow this app to be anything
14709            // below foreground, so it is not worth doing work for it.
14710            app.adjType = "fixed";
14711            app.adjSeq = mAdjSeq;
14712            app.curRawAdj = app.maxAdj;
14713            app.foregroundActivities = false;
14714            app.keeping = true;
14715            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14716            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14717            // System processes can do UI, and when they do we want to have
14718            // them trim their memory after the user leaves the UI.  To
14719            // facilitate this, here we need to determine whether or not it
14720            // is currently showing UI.
14721            app.systemNoUi = true;
14722            if (app == TOP_APP) {
14723                app.systemNoUi = false;
14724            } else if (activitiesSize > 0) {
14725                for (int j = 0; j < activitiesSize; j++) {
14726                    final ActivityRecord r = app.activities.get(j);
14727                    if (r.visible) {
14728                        app.systemNoUi = false;
14729                    }
14730                }
14731            }
14732            if (!app.systemNoUi) {
14733                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14734            }
14735            return (app.curAdj=app.maxAdj);
14736        }
14737
14738        app.keeping = false;
14739        app.systemNoUi = false;
14740
14741        // Determine the importance of the process, starting with most
14742        // important to least, and assign an appropriate OOM adjustment.
14743        int adj;
14744        int schedGroup;
14745        int procState;
14746        boolean foregroundActivities = false;
14747        boolean interesting = false;
14748        BroadcastQueue queue;
14749        if (app == TOP_APP) {
14750            // The last app on the list is the foreground app.
14751            adj = ProcessList.FOREGROUND_APP_ADJ;
14752            schedGroup = Process.THREAD_GROUP_DEFAULT;
14753            app.adjType = "top-activity";
14754            foregroundActivities = true;
14755            interesting = true;
14756            procState = ActivityManager.PROCESS_STATE_TOP;
14757        } else if (app.instrumentationClass != null) {
14758            // Don't want to kill running instrumentation.
14759            adj = ProcessList.FOREGROUND_APP_ADJ;
14760            schedGroup = Process.THREAD_GROUP_DEFAULT;
14761            app.adjType = "instrumentation";
14762            interesting = true;
14763            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14764        } else if ((queue = isReceivingBroadcast(app)) != null) {
14765            // An app that is currently receiving a broadcast also
14766            // counts as being in the foreground for OOM killer purposes.
14767            // It's placed in a sched group based on the nature of the
14768            // broadcast as reflected by which queue it's active in.
14769            adj = ProcessList.FOREGROUND_APP_ADJ;
14770            schedGroup = (queue == mFgBroadcastQueue)
14771                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14772            app.adjType = "broadcast";
14773            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14774        } else if (app.executingServices.size() > 0) {
14775            // An app that is currently executing a service callback also
14776            // counts as being in the foreground.
14777            adj = ProcessList.FOREGROUND_APP_ADJ;
14778            schedGroup = app.execServicesFg ?
14779                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14780            app.adjType = "exec-service";
14781            procState = ActivityManager.PROCESS_STATE_SERVICE;
14782            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14783        } else {
14784            // As far as we know the process is empty.  We may change our mind later.
14785            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14786            // At this point we don't actually know the adjustment.  Use the cached adj
14787            // value that the caller wants us to.
14788            adj = cachedAdj;
14789            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14790            app.cached = true;
14791            app.empty = true;
14792            app.adjType = "cch-empty";
14793        }
14794
14795        // Examine all activities if not already foreground.
14796        if (!foregroundActivities && activitiesSize > 0) {
14797            for (int j = 0; j < activitiesSize; j++) {
14798                final ActivityRecord r = app.activities.get(j);
14799                if (r.app != app) {
14800                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14801                            + app + "?!?");
14802                    continue;
14803                }
14804                if (r.visible) {
14805                    // App has a visible activity; only upgrade adjustment.
14806                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14807                        adj = ProcessList.VISIBLE_APP_ADJ;
14808                        app.adjType = "visible";
14809                    }
14810                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14811                        procState = ActivityManager.PROCESS_STATE_TOP;
14812                    }
14813                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14814                    app.cached = false;
14815                    app.empty = false;
14816                    foregroundActivities = true;
14817                    break;
14818                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14819                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14820                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14821                        app.adjType = "pausing";
14822                    }
14823                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14824                        procState = ActivityManager.PROCESS_STATE_TOP;
14825                    }
14826                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14827                    app.cached = false;
14828                    app.empty = false;
14829                    foregroundActivities = true;
14830                } else if (r.state == ActivityState.STOPPING) {
14831                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14832                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14833                        app.adjType = "stopping";
14834                    }
14835                    // For the process state, we will at this point consider the
14836                    // process to be cached.  It will be cached either as an activity
14837                    // or empty depending on whether the activity is finishing.  We do
14838                    // this so that we can treat the process as cached for purposes of
14839                    // memory trimming (determing current memory level, trim command to
14840                    // send to process) since there can be an arbitrary number of stopping
14841                    // processes and they should soon all go into the cached state.
14842                    if (!r.finishing) {
14843                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14844                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14845                        }
14846                    }
14847                    app.cached = false;
14848                    app.empty = false;
14849                    foregroundActivities = true;
14850                } else {
14851                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14852                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14853                        app.adjType = "cch-act";
14854                    }
14855                }
14856            }
14857        }
14858
14859        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14860            if (app.foregroundServices) {
14861                // The user is aware of this app, so make it visible.
14862                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14863                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14864                app.cached = false;
14865                app.adjType = "fg-service";
14866                schedGroup = Process.THREAD_GROUP_DEFAULT;
14867            } else if (app.forcingToForeground != null) {
14868                // The user is aware of this app, so make it visible.
14869                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14870                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14871                app.cached = false;
14872                app.adjType = "force-fg";
14873                app.adjSource = app.forcingToForeground;
14874                schedGroup = Process.THREAD_GROUP_DEFAULT;
14875            }
14876        }
14877
14878        if (app.foregroundServices) {
14879            interesting = true;
14880        }
14881
14882        if (app == mHeavyWeightProcess) {
14883            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14884                // We don't want to kill the current heavy-weight process.
14885                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14886                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14887                app.cached = false;
14888                app.adjType = "heavy";
14889            }
14890            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14891                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14892            }
14893        }
14894
14895        if (app == mHomeProcess) {
14896            if (adj > ProcessList.HOME_APP_ADJ) {
14897                // This process is hosting what we currently consider to be the
14898                // home app, so we don't want to let it go into the background.
14899                adj = ProcessList.HOME_APP_ADJ;
14900                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14901                app.cached = false;
14902                app.adjType = "home";
14903            }
14904            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14905                procState = ActivityManager.PROCESS_STATE_HOME;
14906            }
14907        }
14908
14909        if (app == mPreviousProcess && app.activities.size() > 0) {
14910            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14911                // This was the previous process that showed UI to the user.
14912                // We want to try to keep it around more aggressively, to give
14913                // a good experience around switching between two apps.
14914                adj = ProcessList.PREVIOUS_APP_ADJ;
14915                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14916                app.cached = false;
14917                app.adjType = "previous";
14918            }
14919            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14920                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14921            }
14922        }
14923
14924        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14925                + " reason=" + app.adjType);
14926
14927        // By default, we use the computed adjustment.  It may be changed if
14928        // there are applications dependent on our services or providers, but
14929        // this gives us a baseline and makes sure we don't get into an
14930        // infinite recursion.
14931        app.adjSeq = mAdjSeq;
14932        app.curRawAdj = adj;
14933        app.hasStartedServices = false;
14934
14935        if (mBackupTarget != null && app == mBackupTarget.app) {
14936            // If possible we want to avoid killing apps while they're being backed up
14937            if (adj > ProcessList.BACKUP_APP_ADJ) {
14938                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14939                adj = ProcessList.BACKUP_APP_ADJ;
14940                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14941                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14942                }
14943                app.adjType = "backup";
14944                app.cached = false;
14945            }
14946            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14947                procState = ActivityManager.PROCESS_STATE_BACKUP;
14948            }
14949        }
14950
14951        boolean mayBeTop = false;
14952
14953        for (int is = app.services.size()-1;
14954                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14955                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14956                        || procState > ActivityManager.PROCESS_STATE_TOP);
14957                is--) {
14958            ServiceRecord s = app.services.valueAt(is);
14959            if (s.startRequested) {
14960                app.hasStartedServices = true;
14961                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14962                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14963                }
14964                if (app.hasShownUi && app != mHomeProcess) {
14965                    // If this process has shown some UI, let it immediately
14966                    // go to the LRU list because it may be pretty heavy with
14967                    // UI stuff.  We'll tag it with a label just to help
14968                    // debug and understand what is going on.
14969                    if (adj > ProcessList.SERVICE_ADJ) {
14970                        app.adjType = "cch-started-ui-services";
14971                    }
14972                } else {
14973                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14974                        // This service has seen some activity within
14975                        // recent memory, so we will keep its process ahead
14976                        // of the background processes.
14977                        if (adj > ProcessList.SERVICE_ADJ) {
14978                            adj = ProcessList.SERVICE_ADJ;
14979                            app.adjType = "started-services";
14980                            app.cached = false;
14981                        }
14982                    }
14983                    // If we have let the service slide into the background
14984                    // state, still have some text describing what it is doing
14985                    // even though the service no longer has an impact.
14986                    if (adj > ProcessList.SERVICE_ADJ) {
14987                        app.adjType = "cch-started-services";
14988                    }
14989                }
14990                // Don't kill this process because it is doing work; it
14991                // has said it is doing work.
14992                app.keeping = true;
14993            }
14994            for (int conni = s.connections.size()-1;
14995                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14996                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14997                            || procState > ActivityManager.PROCESS_STATE_TOP);
14998                    conni--) {
14999                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15000                for (int i = 0;
15001                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15002                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15003                                || procState > ActivityManager.PROCESS_STATE_TOP);
15004                        i++) {
15005                    // XXX should compute this based on the max of
15006                    // all connected clients.
15007                    ConnectionRecord cr = clist.get(i);
15008                    if (cr.binding.client == app) {
15009                        // Binding to ourself is not interesting.
15010                        continue;
15011                    }
15012                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15013                        ProcessRecord client = cr.binding.client;
15014                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15015                                TOP_APP, doingAll, now);
15016                        int clientProcState = client.curProcState;
15017                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15018                            // If the other app is cached for any reason, for purposes here
15019                            // we are going to consider it empty.  The specific cached state
15020                            // doesn't propagate except under certain conditions.
15021                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15022                        }
15023                        String adjType = null;
15024                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15025                            // Not doing bind OOM management, so treat
15026                            // this guy more like a started service.
15027                            if (app.hasShownUi && app != mHomeProcess) {
15028                                // If this process has shown some UI, let it immediately
15029                                // go to the LRU list because it may be pretty heavy with
15030                                // UI stuff.  We'll tag it with a label just to help
15031                                // debug and understand what is going on.
15032                                if (adj > clientAdj) {
15033                                    adjType = "cch-bound-ui-services";
15034                                }
15035                                app.cached = false;
15036                                clientAdj = adj;
15037                                clientProcState = procState;
15038                            } else {
15039                                if (now >= (s.lastActivity
15040                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15041                                    // This service has not seen activity within
15042                                    // recent memory, so allow it to drop to the
15043                                    // LRU list if there is no other reason to keep
15044                                    // it around.  We'll also tag it with a label just
15045                                    // to help debug and undertand what is going on.
15046                                    if (adj > clientAdj) {
15047                                        adjType = "cch-bound-services";
15048                                    }
15049                                    clientAdj = adj;
15050                                }
15051                            }
15052                        }
15053                        if (adj > clientAdj) {
15054                            // If this process has recently shown UI, and
15055                            // the process that is binding to it is less
15056                            // important than being visible, then we don't
15057                            // care about the binding as much as we care
15058                            // about letting this process get into the LRU
15059                            // list to be killed and restarted if needed for
15060                            // memory.
15061                            if (app.hasShownUi && app != mHomeProcess
15062                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15063                                adjType = "cch-bound-ui-services";
15064                            } else {
15065                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15066                                        |Context.BIND_IMPORTANT)) != 0) {
15067                                    adj = clientAdj;
15068                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15069                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15070                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15071                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15072                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15073                                    adj = clientAdj;
15074                                } else {
15075                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15076                                        adj = ProcessList.VISIBLE_APP_ADJ;
15077                                    }
15078                                }
15079                                if (!client.cached) {
15080                                    app.cached = false;
15081                                }
15082                                if (client.keeping) {
15083                                    app.keeping = true;
15084                                }
15085                                adjType = "service";
15086                            }
15087                        }
15088                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15089                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15090                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15091                            }
15092                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15093                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15094                                    // Special handling of clients who are in the top state.
15095                                    // We *may* want to consider this process to be in the
15096                                    // top state as well, but only if there is not another
15097                                    // reason for it to be running.  Being on the top is a
15098                                    // special state, meaning you are specifically running
15099                                    // for the current top app.  If the process is already
15100                                    // running in the background for some other reason, it
15101                                    // is more important to continue considering it to be
15102                                    // in the background state.
15103                                    mayBeTop = true;
15104                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15105                                } else {
15106                                    // Special handling for above-top states (persistent
15107                                    // processes).  These should not bring the current process
15108                                    // into the top state, since they are not on top.  Instead
15109                                    // give them the best state after that.
15110                                    clientProcState =
15111                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15112                                }
15113                            }
15114                        } else {
15115                            if (clientProcState <
15116                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15117                                clientProcState =
15118                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15119                            }
15120                        }
15121                        if (procState > clientProcState) {
15122                            procState = clientProcState;
15123                        }
15124                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15125                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15126                            app.pendingUiClean = true;
15127                        }
15128                        if (adjType != null) {
15129                            app.adjType = adjType;
15130                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15131                                    .REASON_SERVICE_IN_USE;
15132                            app.adjSource = cr.binding.client;
15133                            app.adjSourceOom = clientAdj;
15134                            app.adjTarget = s.name;
15135                        }
15136                    }
15137                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15138                        app.treatLikeActivity = true;
15139                    }
15140                    final ActivityRecord a = cr.activity;
15141                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15142                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15143                                (a.visible || a.state == ActivityState.RESUMED
15144                                 || a.state == ActivityState.PAUSING)) {
15145                            adj = ProcessList.FOREGROUND_APP_ADJ;
15146                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15147                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15148                            }
15149                            app.cached = false;
15150                            app.adjType = "service";
15151                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15152                                    .REASON_SERVICE_IN_USE;
15153                            app.adjSource = a;
15154                            app.adjSourceOom = adj;
15155                            app.adjTarget = s.name;
15156                        }
15157                    }
15158                }
15159            }
15160        }
15161
15162        for (int provi = app.pubProviders.size()-1;
15163                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15164                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15165                        || procState > ActivityManager.PROCESS_STATE_TOP);
15166                provi--) {
15167            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15168            for (int i = cpr.connections.size()-1;
15169                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15170                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15171                            || procState > ActivityManager.PROCESS_STATE_TOP);
15172                    i--) {
15173                ContentProviderConnection conn = cpr.connections.get(i);
15174                ProcessRecord client = conn.client;
15175                if (client == app) {
15176                    // Being our own client is not interesting.
15177                    continue;
15178                }
15179                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15180                int clientProcState = client.curProcState;
15181                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15182                    // If the other app is cached for any reason, for purposes here
15183                    // we are going to consider it empty.
15184                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15185                }
15186                if (adj > clientAdj) {
15187                    if (app.hasShownUi && app != mHomeProcess
15188                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15189                        app.adjType = "cch-ui-provider";
15190                    } else {
15191                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15192                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15193                        app.adjType = "provider";
15194                    }
15195                    app.cached &= client.cached;
15196                    app.keeping |= client.keeping;
15197                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15198                            .REASON_PROVIDER_IN_USE;
15199                    app.adjSource = client;
15200                    app.adjSourceOom = clientAdj;
15201                    app.adjTarget = cpr.name;
15202                }
15203                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15204                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15205                        // Special handling of clients who are in the top state.
15206                        // We *may* want to consider this process to be in the
15207                        // top state as well, but only if there is not another
15208                        // reason for it to be running.  Being on the top is a
15209                        // special state, meaning you are specifically running
15210                        // for the current top app.  If the process is already
15211                        // running in the background for some other reason, it
15212                        // is more important to continue considering it to be
15213                        // in the background state.
15214                        mayBeTop = true;
15215                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15216                    } else {
15217                        // Special handling for above-top states (persistent
15218                        // processes).  These should not bring the current process
15219                        // into the top state, since they are not on top.  Instead
15220                        // give them the best state after that.
15221                        clientProcState =
15222                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15223                    }
15224                }
15225                if (procState > clientProcState) {
15226                    procState = clientProcState;
15227                }
15228                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15229                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15230                }
15231            }
15232            // If the provider has external (non-framework) process
15233            // dependencies, ensure that its adjustment is at least
15234            // FOREGROUND_APP_ADJ.
15235            if (cpr.hasExternalProcessHandles()) {
15236                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15237                    adj = ProcessList.FOREGROUND_APP_ADJ;
15238                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15239                    app.cached = false;
15240                    app.keeping = true;
15241                    app.adjType = "provider";
15242                    app.adjTarget = cpr.name;
15243                }
15244                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15245                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15246                }
15247            }
15248        }
15249
15250        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15251            // A client of one of our services or providers is in the top state.  We
15252            // *may* want to be in the top state, but not if we are already running in
15253            // the background for some other reason.  For the decision here, we are going
15254            // to pick out a few specific states that we want to remain in when a client
15255            // is top (states that tend to be longer-term) and otherwise allow it to go
15256            // to the top state.
15257            switch (procState) {
15258                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15259                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15260                case ActivityManager.PROCESS_STATE_SERVICE:
15261                    // These all are longer-term states, so pull them up to the top
15262                    // of the background states, but not all the way to the top state.
15263                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15264                    break;
15265                default:
15266                    // Otherwise, top is a better choice, so take it.
15267                    procState = ActivityManager.PROCESS_STATE_TOP;
15268                    break;
15269            }
15270        }
15271
15272        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15273            if (app.hasClientActivities) {
15274                // This is a cached process, but with client activities.  Mark it so.
15275                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15276                app.adjType = "cch-client-act";
15277            } else if (app.treatLikeActivity) {
15278                // This is a cached process, but somebody wants us to treat it like it has
15279                // an activity, okay!
15280                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15281                app.adjType = "cch-as-act";
15282            }
15283        }
15284
15285        if (adj == ProcessList.SERVICE_ADJ) {
15286            if (doingAll) {
15287                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15288                mNewNumServiceProcs++;
15289                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15290                if (!app.serviceb) {
15291                    // This service isn't far enough down on the LRU list to
15292                    // normally be a B service, but if we are low on RAM and it
15293                    // is large we want to force it down since we would prefer to
15294                    // keep launcher over it.
15295                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15296                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15297                        app.serviceHighRam = true;
15298                        app.serviceb = true;
15299                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15300                    } else {
15301                        mNewNumAServiceProcs++;
15302                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15303                    }
15304                } else {
15305                    app.serviceHighRam = false;
15306                }
15307            }
15308            if (app.serviceb) {
15309                adj = ProcessList.SERVICE_B_ADJ;
15310            }
15311        }
15312
15313        app.curRawAdj = adj;
15314
15315        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15316        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15317        if (adj > app.maxAdj) {
15318            adj = app.maxAdj;
15319            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15320                schedGroup = Process.THREAD_GROUP_DEFAULT;
15321            }
15322        }
15323        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15324            app.keeping = true;
15325        }
15326
15327        // Do final modification to adj.  Everything we do between here and applying
15328        // the final setAdj must be done in this function, because we will also use
15329        // it when computing the final cached adj later.  Note that we don't need to
15330        // worry about this for max adj above, since max adj will always be used to
15331        // keep it out of the cached vaues.
15332        app.curAdj = app.modifyRawOomAdj(adj);
15333        app.curSchedGroup = schedGroup;
15334        app.curProcState = procState;
15335        app.foregroundActivities = foregroundActivities;
15336
15337        return app.curRawAdj;
15338    }
15339
15340    /**
15341     * Schedule PSS collection of a process.
15342     */
15343    void requestPssLocked(ProcessRecord proc, int procState) {
15344        if (mPendingPssProcesses.contains(proc)) {
15345            return;
15346        }
15347        if (mPendingPssProcesses.size() == 0) {
15348            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15349        }
15350        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15351        proc.pssProcState = procState;
15352        mPendingPssProcesses.add(proc);
15353    }
15354
15355    /**
15356     * Schedule PSS collection of all processes.
15357     */
15358    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15359        if (!always) {
15360            if (now < (mLastFullPssTime +
15361                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15362                return;
15363            }
15364        }
15365        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15366        mLastFullPssTime = now;
15367        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15368        mPendingPssProcesses.clear();
15369        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15370            ProcessRecord app = mLruProcesses.get(i);
15371            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15372                app.pssProcState = app.setProcState;
15373                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15374                        isSleeping(), now);
15375                mPendingPssProcesses.add(app);
15376            }
15377        }
15378        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15379    }
15380
15381    /**
15382     * Ask a given process to GC right now.
15383     */
15384    final void performAppGcLocked(ProcessRecord app) {
15385        try {
15386            app.lastRequestedGc = SystemClock.uptimeMillis();
15387            if (app.thread != null) {
15388                if (app.reportLowMemory) {
15389                    app.reportLowMemory = false;
15390                    app.thread.scheduleLowMemory();
15391                } else {
15392                    app.thread.processInBackground();
15393                }
15394            }
15395        } catch (Exception e) {
15396            // whatever.
15397        }
15398    }
15399
15400    /**
15401     * Returns true if things are idle enough to perform GCs.
15402     */
15403    private final boolean canGcNowLocked() {
15404        boolean processingBroadcasts = false;
15405        for (BroadcastQueue q : mBroadcastQueues) {
15406            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15407                processingBroadcasts = true;
15408            }
15409        }
15410        return !processingBroadcasts
15411                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15412    }
15413
15414    /**
15415     * Perform GCs on all processes that are waiting for it, but only
15416     * if things are idle.
15417     */
15418    final void performAppGcsLocked() {
15419        final int N = mProcessesToGc.size();
15420        if (N <= 0) {
15421            return;
15422        }
15423        if (canGcNowLocked()) {
15424            while (mProcessesToGc.size() > 0) {
15425                ProcessRecord proc = mProcessesToGc.remove(0);
15426                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15427                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15428                            <= SystemClock.uptimeMillis()) {
15429                        // To avoid spamming the system, we will GC processes one
15430                        // at a time, waiting a few seconds between each.
15431                        performAppGcLocked(proc);
15432                        scheduleAppGcsLocked();
15433                        return;
15434                    } else {
15435                        // It hasn't been long enough since we last GCed this
15436                        // process...  put it in the list to wait for its time.
15437                        addProcessToGcListLocked(proc);
15438                        break;
15439                    }
15440                }
15441            }
15442
15443            scheduleAppGcsLocked();
15444        }
15445    }
15446
15447    /**
15448     * If all looks good, perform GCs on all processes waiting for them.
15449     */
15450    final void performAppGcsIfAppropriateLocked() {
15451        if (canGcNowLocked()) {
15452            performAppGcsLocked();
15453            return;
15454        }
15455        // Still not idle, wait some more.
15456        scheduleAppGcsLocked();
15457    }
15458
15459    /**
15460     * Schedule the execution of all pending app GCs.
15461     */
15462    final void scheduleAppGcsLocked() {
15463        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15464
15465        if (mProcessesToGc.size() > 0) {
15466            // Schedule a GC for the time to the next process.
15467            ProcessRecord proc = mProcessesToGc.get(0);
15468            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15469
15470            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15471            long now = SystemClock.uptimeMillis();
15472            if (when < (now+GC_TIMEOUT)) {
15473                when = now + GC_TIMEOUT;
15474            }
15475            mHandler.sendMessageAtTime(msg, when);
15476        }
15477    }
15478
15479    /**
15480     * Add a process to the array of processes waiting to be GCed.  Keeps the
15481     * list in sorted order by the last GC time.  The process can't already be
15482     * on the list.
15483     */
15484    final void addProcessToGcListLocked(ProcessRecord proc) {
15485        boolean added = false;
15486        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15487            if (mProcessesToGc.get(i).lastRequestedGc <
15488                    proc.lastRequestedGc) {
15489                added = true;
15490                mProcessesToGc.add(i+1, proc);
15491                break;
15492            }
15493        }
15494        if (!added) {
15495            mProcessesToGc.add(0, proc);
15496        }
15497    }
15498
15499    /**
15500     * Set up to ask a process to GC itself.  This will either do it
15501     * immediately, or put it on the list of processes to gc the next
15502     * time things are idle.
15503     */
15504    final void scheduleAppGcLocked(ProcessRecord app) {
15505        long now = SystemClock.uptimeMillis();
15506        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15507            return;
15508        }
15509        if (!mProcessesToGc.contains(app)) {
15510            addProcessToGcListLocked(app);
15511            scheduleAppGcsLocked();
15512        }
15513    }
15514
15515    final void checkExcessivePowerUsageLocked(boolean doKills) {
15516        updateCpuStatsNow();
15517
15518        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15519        boolean doWakeKills = doKills;
15520        boolean doCpuKills = doKills;
15521        if (mLastPowerCheckRealtime == 0) {
15522            doWakeKills = false;
15523        }
15524        if (mLastPowerCheckUptime == 0) {
15525            doCpuKills = false;
15526        }
15527        if (stats.isScreenOn()) {
15528            doWakeKills = false;
15529        }
15530        final long curRealtime = SystemClock.elapsedRealtime();
15531        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15532        final long curUptime = SystemClock.uptimeMillis();
15533        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15534        mLastPowerCheckRealtime = curRealtime;
15535        mLastPowerCheckUptime = curUptime;
15536        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15537            doWakeKills = false;
15538        }
15539        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15540            doCpuKills = false;
15541        }
15542        int i = mLruProcesses.size();
15543        while (i > 0) {
15544            i--;
15545            ProcessRecord app = mLruProcesses.get(i);
15546            if (!app.keeping) {
15547                long wtime;
15548                synchronized (stats) {
15549                    wtime = stats.getProcessWakeTime(app.info.uid,
15550                            app.pid, curRealtime);
15551                }
15552                long wtimeUsed = wtime - app.lastWakeTime;
15553                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15554                if (DEBUG_POWER) {
15555                    StringBuilder sb = new StringBuilder(128);
15556                    sb.append("Wake for ");
15557                    app.toShortString(sb);
15558                    sb.append(": over ");
15559                    TimeUtils.formatDuration(realtimeSince, sb);
15560                    sb.append(" used ");
15561                    TimeUtils.formatDuration(wtimeUsed, sb);
15562                    sb.append(" (");
15563                    sb.append((wtimeUsed*100)/realtimeSince);
15564                    sb.append("%)");
15565                    Slog.i(TAG, sb.toString());
15566                    sb.setLength(0);
15567                    sb.append("CPU for ");
15568                    app.toShortString(sb);
15569                    sb.append(": over ");
15570                    TimeUtils.formatDuration(uptimeSince, sb);
15571                    sb.append(" used ");
15572                    TimeUtils.formatDuration(cputimeUsed, sb);
15573                    sb.append(" (");
15574                    sb.append((cputimeUsed*100)/uptimeSince);
15575                    sb.append("%)");
15576                    Slog.i(TAG, sb.toString());
15577                }
15578                // If a process has held a wake lock for more
15579                // than 50% of the time during this period,
15580                // that sounds bad.  Kill!
15581                if (doWakeKills && realtimeSince > 0
15582                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15583                    synchronized (stats) {
15584                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15585                                realtimeSince, wtimeUsed);
15586                    }
15587                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15588                            + " during " + realtimeSince);
15589                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15590                } else if (doCpuKills && uptimeSince > 0
15591                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15592                    synchronized (stats) {
15593                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15594                                uptimeSince, cputimeUsed);
15595                    }
15596                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15597                            + " during " + uptimeSince);
15598                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15599                } else {
15600                    app.lastWakeTime = wtime;
15601                    app.lastCpuTime = app.curCpuTime;
15602                }
15603            }
15604        }
15605    }
15606
15607    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15608            ProcessRecord TOP_APP, boolean doingAll, long now) {
15609        boolean success = true;
15610
15611        if (app.curRawAdj != app.setRawAdj) {
15612            if (wasKeeping && !app.keeping) {
15613                // This app is no longer something we want to keep.  Note
15614                // its current wake lock time to later know to kill it if
15615                // it is not behaving well.
15616                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15617                synchronized (stats) {
15618                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15619                            app.pid, SystemClock.elapsedRealtime());
15620                }
15621                app.lastCpuTime = app.curCpuTime;
15622            }
15623
15624            app.setRawAdj = app.curRawAdj;
15625        }
15626
15627        int changes = 0;
15628
15629        if (app.curAdj != app.setAdj) {
15630            ProcessList.setOomAdj(app.pid, app.curAdj);
15631            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15632                TAG, "Set " + app.pid + " " + app.processName +
15633                " adj " + app.curAdj + ": " + app.adjType);
15634            app.setAdj = app.curAdj;
15635        }
15636
15637        if (app.setSchedGroup != app.curSchedGroup) {
15638            app.setSchedGroup = app.curSchedGroup;
15639            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15640                    "Setting process group of " + app.processName
15641                    + " to " + app.curSchedGroup);
15642            if (app.waitingToKill != null &&
15643                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15644                killUnneededProcessLocked(app, app.waitingToKill);
15645                success = false;
15646            } else {
15647                if (true) {
15648                    long oldId = Binder.clearCallingIdentity();
15649                    try {
15650                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15651                    } catch (Exception e) {
15652                        Slog.w(TAG, "Failed setting process group of " + app.pid
15653                                + " to " + app.curSchedGroup);
15654                        e.printStackTrace();
15655                    } finally {
15656                        Binder.restoreCallingIdentity(oldId);
15657                    }
15658                } else {
15659                    if (app.thread != null) {
15660                        try {
15661                            app.thread.setSchedulingGroup(app.curSchedGroup);
15662                        } catch (RemoteException e) {
15663                        }
15664                    }
15665                }
15666                Process.setSwappiness(app.pid,
15667                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15668            }
15669        }
15670        if (app.repForegroundActivities != app.foregroundActivities) {
15671            app.repForegroundActivities = app.foregroundActivities;
15672            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15673        }
15674        if (app.repProcState != app.curProcState) {
15675            app.repProcState = app.curProcState;
15676            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15677            if (app.thread != null) {
15678                try {
15679                    if (false) {
15680                        //RuntimeException h = new RuntimeException("here");
15681                        Slog.i(TAG, "Sending new process state " + app.repProcState
15682                                + " to " + app /*, h*/);
15683                    }
15684                    app.thread.setProcessState(app.repProcState);
15685                } catch (RemoteException e) {
15686                }
15687            }
15688        }
15689        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15690                app.setProcState)) {
15691            app.lastStateTime = now;
15692            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15693                    isSleeping(), now);
15694            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15695                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15696                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15697                    + (app.nextPssTime-now) + ": " + app);
15698        } else {
15699            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15700                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15701                requestPssLocked(app, app.setProcState);
15702                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15703                        isSleeping(), now);
15704            } else if (false && DEBUG_PSS) {
15705                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15706            }
15707        }
15708        if (app.setProcState != app.curProcState) {
15709            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15710                    "Proc state change of " + app.processName
15711                    + " to " + app.curProcState);
15712            app.setProcState = app.curProcState;
15713            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15714                app.notCachedSinceIdle = false;
15715            }
15716            if (!doingAll) {
15717                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15718            } else {
15719                app.procStateChanged = true;
15720            }
15721        }
15722
15723        if (changes != 0) {
15724            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15725            int i = mPendingProcessChanges.size()-1;
15726            ProcessChangeItem item = null;
15727            while (i >= 0) {
15728                item = mPendingProcessChanges.get(i);
15729                if (item.pid == app.pid) {
15730                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15731                    break;
15732                }
15733                i--;
15734            }
15735            if (i < 0) {
15736                // No existing item in pending changes; need a new one.
15737                final int NA = mAvailProcessChanges.size();
15738                if (NA > 0) {
15739                    item = mAvailProcessChanges.remove(NA-1);
15740                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15741                } else {
15742                    item = new ProcessChangeItem();
15743                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15744                }
15745                item.changes = 0;
15746                item.pid = app.pid;
15747                item.uid = app.info.uid;
15748                if (mPendingProcessChanges.size() == 0) {
15749                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15750                            "*** Enqueueing dispatch processes changed!");
15751                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15752                }
15753                mPendingProcessChanges.add(item);
15754            }
15755            item.changes |= changes;
15756            item.processState = app.repProcState;
15757            item.foregroundActivities = app.repForegroundActivities;
15758            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15759                    + Integer.toHexString(System.identityHashCode(item))
15760                    + " " + app.toShortString() + ": changes=" + item.changes
15761                    + " procState=" + item.processState
15762                    + " foreground=" + item.foregroundActivities
15763                    + " type=" + app.adjType + " source=" + app.adjSource
15764                    + " target=" + app.adjTarget);
15765        }
15766
15767        return success;
15768    }
15769
15770    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15771        if (proc.thread != null && proc.baseProcessTracker != null) {
15772            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15773        }
15774    }
15775
15776    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15777            ProcessRecord TOP_APP, boolean doingAll, long now) {
15778        if (app.thread == null) {
15779            return false;
15780        }
15781
15782        final boolean wasKeeping = app.keeping;
15783
15784        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15785
15786        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15787    }
15788
15789    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15790            boolean oomAdj) {
15791        if (isForeground != proc.foregroundServices) {
15792            proc.foregroundServices = isForeground;
15793            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15794                    proc.info.uid);
15795            if (isForeground) {
15796                if (curProcs == null) {
15797                    curProcs = new ArrayList<ProcessRecord>();
15798                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15799                }
15800                if (!curProcs.contains(proc)) {
15801                    curProcs.add(proc);
15802                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15803                            proc.info.packageName, proc.info.uid);
15804                }
15805            } else {
15806                if (curProcs != null) {
15807                    if (curProcs.remove(proc)) {
15808                        mBatteryStatsService.noteEvent(
15809                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15810                                proc.info.packageName, proc.info.uid);
15811                        if (curProcs.size() <= 0) {
15812                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15813                        }
15814                    }
15815                }
15816            }
15817            if (oomAdj) {
15818                updateOomAdjLocked();
15819            }
15820        }
15821    }
15822
15823    private final ActivityRecord resumedAppLocked() {
15824        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15825        String pkg;
15826        int uid;
15827        if (act != null && !act.sleeping) {
15828            pkg = act.packageName;
15829            uid = act.info.applicationInfo.uid;
15830        } else {
15831            pkg = null;
15832            uid = -1;
15833        }
15834        // Has the UID or resumed package name changed?
15835        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15836                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15837            if (mCurResumedPackage != null) {
15838                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15839                        mCurResumedPackage, mCurResumedUid);
15840            }
15841            mCurResumedPackage = pkg;
15842            mCurResumedUid = uid;
15843            if (mCurResumedPackage != null) {
15844                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15845                        mCurResumedPackage, mCurResumedUid);
15846            }
15847        }
15848        return act;
15849    }
15850
15851    final boolean updateOomAdjLocked(ProcessRecord app) {
15852        final ActivityRecord TOP_ACT = resumedAppLocked();
15853        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15854        final boolean wasCached = app.cached;
15855
15856        mAdjSeq++;
15857
15858        // This is the desired cached adjusment we want to tell it to use.
15859        // If our app is currently cached, we know it, and that is it.  Otherwise,
15860        // we don't know it yet, and it needs to now be cached we will then
15861        // need to do a complete oom adj.
15862        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15863                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15864        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15865                SystemClock.uptimeMillis());
15866        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15867            // Changed to/from cached state, so apps after it in the LRU
15868            // list may also be changed.
15869            updateOomAdjLocked();
15870        }
15871        return success;
15872    }
15873
15874    final void updateOomAdjLocked() {
15875        final ActivityRecord TOP_ACT = resumedAppLocked();
15876        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15877        final long now = SystemClock.uptimeMillis();
15878        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15879        final int N = mLruProcesses.size();
15880
15881        if (false) {
15882            RuntimeException e = new RuntimeException();
15883            e.fillInStackTrace();
15884            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15885        }
15886
15887        mAdjSeq++;
15888        mNewNumServiceProcs = 0;
15889        mNewNumAServiceProcs = 0;
15890
15891        final int emptyProcessLimit;
15892        final int cachedProcessLimit;
15893        if (mProcessLimit <= 0) {
15894            emptyProcessLimit = cachedProcessLimit = 0;
15895        } else if (mProcessLimit == 1) {
15896            emptyProcessLimit = 1;
15897            cachedProcessLimit = 0;
15898        } else {
15899            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15900            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15901        }
15902
15903        // Let's determine how many processes we have running vs.
15904        // how many slots we have for background processes; we may want
15905        // to put multiple processes in a slot of there are enough of
15906        // them.
15907        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15908                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15909        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15910        if (numEmptyProcs > cachedProcessLimit) {
15911            // If there are more empty processes than our limit on cached
15912            // processes, then use the cached process limit for the factor.
15913            // This ensures that the really old empty processes get pushed
15914            // down to the bottom, so if we are running low on memory we will
15915            // have a better chance at keeping around more cached processes
15916            // instead of a gazillion empty processes.
15917            numEmptyProcs = cachedProcessLimit;
15918        }
15919        int emptyFactor = numEmptyProcs/numSlots;
15920        if (emptyFactor < 1) emptyFactor = 1;
15921        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15922        if (cachedFactor < 1) cachedFactor = 1;
15923        int stepCached = 0;
15924        int stepEmpty = 0;
15925        int numCached = 0;
15926        int numEmpty = 0;
15927        int numTrimming = 0;
15928
15929        mNumNonCachedProcs = 0;
15930        mNumCachedHiddenProcs = 0;
15931
15932        // First update the OOM adjustment for each of the
15933        // application processes based on their current state.
15934        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15935        int nextCachedAdj = curCachedAdj+1;
15936        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15937        int nextEmptyAdj = curEmptyAdj+2;
15938        for (int i=N-1; i>=0; i--) {
15939            ProcessRecord app = mLruProcesses.get(i);
15940            if (!app.killedByAm && app.thread != null) {
15941                app.procStateChanged = false;
15942                final boolean wasKeeping = app.keeping;
15943                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15944
15945                // If we haven't yet assigned the final cached adj
15946                // to the process, do that now.
15947                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15948                    switch (app.curProcState) {
15949                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15950                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15951                            // This process is a cached process holding activities...
15952                            // assign it the next cached value for that type, and then
15953                            // step that cached level.
15954                            app.curRawAdj = curCachedAdj;
15955                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15956                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15957                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15958                                    + ")");
15959                            if (curCachedAdj != nextCachedAdj) {
15960                                stepCached++;
15961                                if (stepCached >= cachedFactor) {
15962                                    stepCached = 0;
15963                                    curCachedAdj = nextCachedAdj;
15964                                    nextCachedAdj += 2;
15965                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15966                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15967                                    }
15968                                }
15969                            }
15970                            break;
15971                        default:
15972                            // For everything else, assign next empty cached process
15973                            // level and bump that up.  Note that this means that
15974                            // long-running services that have dropped down to the
15975                            // cached level will be treated as empty (since their process
15976                            // state is still as a service), which is what we want.
15977                            app.curRawAdj = curEmptyAdj;
15978                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15979                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15980                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15981                                    + ")");
15982                            if (curEmptyAdj != nextEmptyAdj) {
15983                                stepEmpty++;
15984                                if (stepEmpty >= emptyFactor) {
15985                                    stepEmpty = 0;
15986                                    curEmptyAdj = nextEmptyAdj;
15987                                    nextEmptyAdj += 2;
15988                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15989                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15990                                    }
15991                                }
15992                            }
15993                            break;
15994                    }
15995                }
15996
15997                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15998
15999                // Count the number of process types.
16000                switch (app.curProcState) {
16001                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16002                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16003                        mNumCachedHiddenProcs++;
16004                        numCached++;
16005                        if (numCached > cachedProcessLimit) {
16006                            killUnneededProcessLocked(app, "cached #" + numCached);
16007                        }
16008                        break;
16009                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16010                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16011                                && app.lastActivityTime < oldTime) {
16012                            killUnneededProcessLocked(app, "empty for "
16013                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16014                                    / 1000) + "s");
16015                        } else {
16016                            numEmpty++;
16017                            if (numEmpty > emptyProcessLimit) {
16018                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16019                            }
16020                        }
16021                        break;
16022                    default:
16023                        mNumNonCachedProcs++;
16024                        break;
16025                }
16026
16027                if (app.isolated && app.services.size() <= 0) {
16028                    // If this is an isolated process, and there are no
16029                    // services running in it, then the process is no longer
16030                    // needed.  We agressively kill these because we can by
16031                    // definition not re-use the same process again, and it is
16032                    // good to avoid having whatever code was running in them
16033                    // left sitting around after no longer needed.
16034                    killUnneededProcessLocked(app, "isolated not needed");
16035                }
16036
16037                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16038                        && !app.killedByAm) {
16039                    numTrimming++;
16040                }
16041            }
16042        }
16043
16044        mNumServiceProcs = mNewNumServiceProcs;
16045
16046        // Now determine the memory trimming level of background processes.
16047        // Unfortunately we need to start at the back of the list to do this
16048        // properly.  We only do this if the number of background apps we
16049        // are managing to keep around is less than half the maximum we desire;
16050        // if we are keeping a good number around, we'll let them use whatever
16051        // memory they want.
16052        final int numCachedAndEmpty = numCached + numEmpty;
16053        int memFactor;
16054        if (numCached <= ProcessList.TRIM_CACHED_APPS
16055                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16056            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16057                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16058            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16059                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16060            } else {
16061                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16062            }
16063        } else {
16064            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16065        }
16066        // We always allow the memory level to go up (better).  We only allow it to go
16067        // down if we are in a state where that is allowed, *and* the total number of processes
16068        // has gone down since last time.
16069        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16070                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16071                + " last=" + mLastNumProcesses);
16072        if (memFactor > mLastMemoryLevel) {
16073            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16074                memFactor = mLastMemoryLevel;
16075                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16076            }
16077        }
16078        mLastMemoryLevel = memFactor;
16079        mLastNumProcesses = mLruProcesses.size();
16080        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16081        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16082        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16083            if (mLowRamStartTime == 0) {
16084                mLowRamStartTime = now;
16085            }
16086            int step = 0;
16087            int fgTrimLevel;
16088            switch (memFactor) {
16089                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16090                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16091                    break;
16092                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16093                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16094                    break;
16095                default:
16096                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16097                    break;
16098            }
16099            int factor = numTrimming/3;
16100            int minFactor = 2;
16101            if (mHomeProcess != null) minFactor++;
16102            if (mPreviousProcess != null) minFactor++;
16103            if (factor < minFactor) factor = minFactor;
16104            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16105            for (int i=N-1; i>=0; i--) {
16106                ProcessRecord app = mLruProcesses.get(i);
16107                if (allChanged || app.procStateChanged) {
16108                    setProcessTrackerState(app, trackerMemFactor, now);
16109                    app.procStateChanged = false;
16110                }
16111                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16112                        && !app.killedByAm) {
16113                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16114                        try {
16115                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16116                                    "Trimming memory of " + app.processName
16117                                    + " to " + curLevel);
16118                            app.thread.scheduleTrimMemory(curLevel);
16119                        } catch (RemoteException e) {
16120                        }
16121                        if (false) {
16122                            // For now we won't do this; our memory trimming seems
16123                            // to be good enough at this point that destroying
16124                            // activities causes more harm than good.
16125                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16126                                    && app != mHomeProcess && app != mPreviousProcess) {
16127                                // Need to do this on its own message because the stack may not
16128                                // be in a consistent state at this point.
16129                                // For these apps we will also finish their activities
16130                                // to help them free memory.
16131                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16132                            }
16133                        }
16134                    }
16135                    app.trimMemoryLevel = curLevel;
16136                    step++;
16137                    if (step >= factor) {
16138                        step = 0;
16139                        switch (curLevel) {
16140                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16141                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16142                                break;
16143                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16144                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16145                                break;
16146                        }
16147                    }
16148                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16149                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16150                            && app.thread != null) {
16151                        try {
16152                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16153                                    "Trimming memory of heavy-weight " + app.processName
16154                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16155                            app.thread.scheduleTrimMemory(
16156                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16157                        } catch (RemoteException e) {
16158                        }
16159                    }
16160                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16161                } else {
16162                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16163                            || app.systemNoUi) && app.pendingUiClean) {
16164                        // If this application is now in the background and it
16165                        // had done UI, then give it the special trim level to
16166                        // have it free UI resources.
16167                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16168                        if (app.trimMemoryLevel < level && app.thread != null) {
16169                            try {
16170                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16171                                        "Trimming memory of bg-ui " + app.processName
16172                                        + " to " + level);
16173                                app.thread.scheduleTrimMemory(level);
16174                            } catch (RemoteException e) {
16175                            }
16176                        }
16177                        app.pendingUiClean = false;
16178                    }
16179                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16180                        try {
16181                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16182                                    "Trimming memory of fg " + app.processName
16183                                    + " to " + fgTrimLevel);
16184                            app.thread.scheduleTrimMemory(fgTrimLevel);
16185                        } catch (RemoteException e) {
16186                        }
16187                    }
16188                    app.trimMemoryLevel = fgTrimLevel;
16189                }
16190            }
16191        } else {
16192            if (mLowRamStartTime != 0) {
16193                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16194                mLowRamStartTime = 0;
16195            }
16196            for (int i=N-1; i>=0; i--) {
16197                ProcessRecord app = mLruProcesses.get(i);
16198                if (allChanged || app.procStateChanged) {
16199                    setProcessTrackerState(app, trackerMemFactor, now);
16200                    app.procStateChanged = false;
16201                }
16202                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16203                        || app.systemNoUi) && app.pendingUiClean) {
16204                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16205                            && app.thread != null) {
16206                        try {
16207                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16208                                    "Trimming memory of ui hidden " + app.processName
16209                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16210                            app.thread.scheduleTrimMemory(
16211                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16212                        } catch (RemoteException e) {
16213                        }
16214                    }
16215                    app.pendingUiClean = false;
16216                }
16217                app.trimMemoryLevel = 0;
16218            }
16219        }
16220
16221        if (mAlwaysFinishActivities) {
16222            // Need to do this on its own message because the stack may not
16223            // be in a consistent state at this point.
16224            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16225        }
16226
16227        if (allChanged) {
16228            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16229        }
16230
16231        if (mProcessStats.shouldWriteNowLocked(now)) {
16232            mHandler.post(new Runnable() {
16233                @Override public void run() {
16234                    synchronized (ActivityManagerService.this) {
16235                        mProcessStats.writeStateAsyncLocked();
16236                    }
16237                }
16238            });
16239        }
16240
16241        if (DEBUG_OOM_ADJ) {
16242            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16243        }
16244    }
16245
16246    final void trimApplications() {
16247        synchronized (this) {
16248            int i;
16249
16250            // First remove any unused application processes whose package
16251            // has been removed.
16252            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16253                final ProcessRecord app = mRemovedProcesses.get(i);
16254                if (app.activities.size() == 0
16255                        && app.curReceiver == null && app.services.size() == 0) {
16256                    Slog.i(
16257                        TAG, "Exiting empty application process "
16258                        + app.processName + " ("
16259                        + (app.thread != null ? app.thread.asBinder() : null)
16260                        + ")\n");
16261                    if (app.pid > 0 && app.pid != MY_PID) {
16262                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16263                                app.processName, app.setAdj, "empty");
16264                        app.killedByAm = true;
16265                        Process.killProcessQuiet(app.pid);
16266                    } else {
16267                        try {
16268                            app.thread.scheduleExit();
16269                        } catch (Exception e) {
16270                            // Ignore exceptions.
16271                        }
16272                    }
16273                    cleanUpApplicationRecordLocked(app, false, true, -1);
16274                    mRemovedProcesses.remove(i);
16275
16276                    if (app.persistent) {
16277                        if (app.persistent) {
16278                            addAppLocked(app.info, false);
16279                        }
16280                    }
16281                }
16282            }
16283
16284            // Now update the oom adj for all processes.
16285            updateOomAdjLocked();
16286        }
16287    }
16288
16289    /** This method sends the specified signal to each of the persistent apps */
16290    public void signalPersistentProcesses(int sig) throws RemoteException {
16291        if (sig != Process.SIGNAL_USR1) {
16292            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16293        }
16294
16295        synchronized (this) {
16296            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16297                    != PackageManager.PERMISSION_GRANTED) {
16298                throw new SecurityException("Requires permission "
16299                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16300            }
16301
16302            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16303                ProcessRecord r = mLruProcesses.get(i);
16304                if (r.thread != null && r.persistent) {
16305                    Process.sendSignal(r.pid, sig);
16306                }
16307            }
16308        }
16309    }
16310
16311    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16312        if (proc == null || proc == mProfileProc) {
16313            proc = mProfileProc;
16314            path = mProfileFile;
16315            profileType = mProfileType;
16316            clearProfilerLocked();
16317        }
16318        if (proc == null) {
16319            return;
16320        }
16321        try {
16322            proc.thread.profilerControl(false, path, null, profileType);
16323        } catch (RemoteException e) {
16324            throw new IllegalStateException("Process disappeared");
16325        }
16326    }
16327
16328    private void clearProfilerLocked() {
16329        if (mProfileFd != null) {
16330            try {
16331                mProfileFd.close();
16332            } catch (IOException e) {
16333            }
16334        }
16335        mProfileApp = null;
16336        mProfileProc = null;
16337        mProfileFile = null;
16338        mProfileType = 0;
16339        mAutoStopProfiler = false;
16340    }
16341
16342    public boolean profileControl(String process, int userId, boolean start,
16343            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16344
16345        try {
16346            synchronized (this) {
16347                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16348                // its own permission.
16349                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16350                        != PackageManager.PERMISSION_GRANTED) {
16351                    throw new SecurityException("Requires permission "
16352                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16353                }
16354
16355                if (start && fd == null) {
16356                    throw new IllegalArgumentException("null fd");
16357                }
16358
16359                ProcessRecord proc = null;
16360                if (process != null) {
16361                    proc = findProcessLocked(process, userId, "profileControl");
16362                }
16363
16364                if (start && (proc == null || proc.thread == null)) {
16365                    throw new IllegalArgumentException("Unknown process: " + process);
16366                }
16367
16368                if (start) {
16369                    stopProfilerLocked(null, null, 0);
16370                    setProfileApp(proc.info, proc.processName, path, fd, false);
16371                    mProfileProc = proc;
16372                    mProfileType = profileType;
16373                    try {
16374                        fd = fd.dup();
16375                    } catch (IOException e) {
16376                        fd = null;
16377                    }
16378                    proc.thread.profilerControl(start, path, fd, profileType);
16379                    fd = null;
16380                    mProfileFd = null;
16381                } else {
16382                    stopProfilerLocked(proc, path, profileType);
16383                    if (fd != null) {
16384                        try {
16385                            fd.close();
16386                        } catch (IOException e) {
16387                        }
16388                    }
16389                }
16390
16391                return true;
16392            }
16393        } catch (RemoteException e) {
16394            throw new IllegalStateException("Process disappeared");
16395        } finally {
16396            if (fd != null) {
16397                try {
16398                    fd.close();
16399                } catch (IOException e) {
16400                }
16401            }
16402        }
16403    }
16404
16405    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16406        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16407                userId, true, true, callName, null);
16408        ProcessRecord proc = null;
16409        try {
16410            int pid = Integer.parseInt(process);
16411            synchronized (mPidsSelfLocked) {
16412                proc = mPidsSelfLocked.get(pid);
16413            }
16414        } catch (NumberFormatException e) {
16415        }
16416
16417        if (proc == null) {
16418            ArrayMap<String, SparseArray<ProcessRecord>> all
16419                    = mProcessNames.getMap();
16420            SparseArray<ProcessRecord> procs = all.get(process);
16421            if (procs != null && procs.size() > 0) {
16422                proc = procs.valueAt(0);
16423                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16424                    for (int i=1; i<procs.size(); i++) {
16425                        ProcessRecord thisProc = procs.valueAt(i);
16426                        if (thisProc.userId == userId) {
16427                            proc = thisProc;
16428                            break;
16429                        }
16430                    }
16431                }
16432            }
16433        }
16434
16435        return proc;
16436    }
16437
16438    public boolean dumpHeap(String process, int userId, boolean managed,
16439            String path, ParcelFileDescriptor fd) throws RemoteException {
16440
16441        try {
16442            synchronized (this) {
16443                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16444                // its own permission (same as profileControl).
16445                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16446                        != PackageManager.PERMISSION_GRANTED) {
16447                    throw new SecurityException("Requires permission "
16448                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16449                }
16450
16451                if (fd == null) {
16452                    throw new IllegalArgumentException("null fd");
16453                }
16454
16455                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16456                if (proc == null || proc.thread == null) {
16457                    throw new IllegalArgumentException("Unknown process: " + process);
16458                }
16459
16460                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16461                if (!isDebuggable) {
16462                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16463                        throw new SecurityException("Process not debuggable: " + proc);
16464                    }
16465                }
16466
16467                proc.thread.dumpHeap(managed, path, fd);
16468                fd = null;
16469                return true;
16470            }
16471        } catch (RemoteException e) {
16472            throw new IllegalStateException("Process disappeared");
16473        } finally {
16474            if (fd != null) {
16475                try {
16476                    fd.close();
16477                } catch (IOException e) {
16478                }
16479            }
16480        }
16481    }
16482
16483    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16484    public void monitor() {
16485        synchronized (this) { }
16486    }
16487
16488    void onCoreSettingsChange(Bundle settings) {
16489        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16490            ProcessRecord processRecord = mLruProcesses.get(i);
16491            try {
16492                if (processRecord.thread != null) {
16493                    processRecord.thread.setCoreSettings(settings);
16494                }
16495            } catch (RemoteException re) {
16496                /* ignore */
16497            }
16498        }
16499    }
16500
16501    // Multi-user methods
16502
16503    /**
16504     * Start user, if its not already running, but don't bring it to foreground.
16505     */
16506    @Override
16507    public boolean startUserInBackground(final int userId) {
16508        return startUser(userId, /* foreground */ false);
16509    }
16510
16511    /**
16512     * Refreshes the list of users related to the current user when either a
16513     * user switch happens or when a new related user is started in the
16514     * background.
16515     */
16516    private void updateCurrentProfileIdsLocked() {
16517        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16518                mCurrentUserId, false /* enabledOnly */);
16519        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16520        for (int i = 0; i < currentProfileIds.length; i++) {
16521            currentProfileIds[i] = profiles.get(i).id;
16522        }
16523        mCurrentProfileIds = currentProfileIds;
16524    }
16525
16526    private Set getProfileIdsLocked(int userId) {
16527        Set userIds = new HashSet<Integer>();
16528        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16529                userId, false /* enabledOnly */);
16530        for (UserInfo user : profiles) {
16531            userIds.add(Integer.valueOf(user.id));
16532        }
16533        return userIds;
16534    }
16535
16536    @Override
16537    public boolean switchUser(final int userId) {
16538        return startUser(userId, /* foregound */ true);
16539    }
16540
16541    private boolean startUser(final int userId, boolean foreground) {
16542        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16543                != PackageManager.PERMISSION_GRANTED) {
16544            String msg = "Permission Denial: switchUser() from pid="
16545                    + Binder.getCallingPid()
16546                    + ", uid=" + Binder.getCallingUid()
16547                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16548            Slog.w(TAG, msg);
16549            throw new SecurityException(msg);
16550        }
16551
16552        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16553
16554        final long ident = Binder.clearCallingIdentity();
16555        try {
16556            synchronized (this) {
16557                final int oldUserId = mCurrentUserId;
16558                if (oldUserId == userId) {
16559                    return true;
16560                }
16561
16562                mStackSupervisor.setLockTaskModeLocked(null);
16563
16564                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16565                if (userInfo == null) {
16566                    Slog.w(TAG, "No user info for user #" + userId);
16567                    return false;
16568                }
16569
16570                if (foreground) {
16571                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16572                            R.anim.screen_user_enter);
16573                }
16574
16575                boolean needStart = false;
16576
16577                // If the user we are switching to is not currently started, then
16578                // we need to start it now.
16579                if (mStartedUsers.get(userId) == null) {
16580                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16581                    updateStartedUserArrayLocked();
16582                    needStart = true;
16583                }
16584
16585                final Integer userIdInt = Integer.valueOf(userId);
16586                mUserLru.remove(userIdInt);
16587                mUserLru.add(userIdInt);
16588
16589                if (foreground) {
16590                    mCurrentUserId = userId;
16591                    updateCurrentProfileIdsLocked();
16592                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16593                    // Once the internal notion of the active user has switched, we lock the device
16594                    // with the option to show the user switcher on the keyguard.
16595                    mWindowManager.lockNow(null);
16596                } else {
16597                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16598                    updateCurrentProfileIdsLocked();
16599                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16600                    mUserLru.remove(currentUserIdInt);
16601                    mUserLru.add(currentUserIdInt);
16602                }
16603
16604                final UserStartedState uss = mStartedUsers.get(userId);
16605
16606                // Make sure user is in the started state.  If it is currently
16607                // stopping, we need to knock that off.
16608                if (uss.mState == UserStartedState.STATE_STOPPING) {
16609                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16610                    // so we can just fairly silently bring the user back from
16611                    // the almost-dead.
16612                    uss.mState = UserStartedState.STATE_RUNNING;
16613                    updateStartedUserArrayLocked();
16614                    needStart = true;
16615                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16616                    // This means ACTION_SHUTDOWN has been sent, so we will
16617                    // need to treat this as a new boot of the user.
16618                    uss.mState = UserStartedState.STATE_BOOTING;
16619                    updateStartedUserArrayLocked();
16620                    needStart = true;
16621                }
16622
16623                if (uss.mState == UserStartedState.STATE_BOOTING) {
16624                    // Booting up a new user, need to tell system services about it.
16625                    // Note that this is on the same handler as scheduling of broadcasts,
16626                    // which is important because it needs to go first.
16627                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16628                }
16629
16630                if (foreground) {
16631                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16632                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16633                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16634                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16635                            oldUserId, userId, uss));
16636                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16637                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16638                }
16639
16640                if (needStart) {
16641                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16642                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16643                            | Intent.FLAG_RECEIVER_FOREGROUND);
16644                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16645                    broadcastIntentLocked(null, null, intent,
16646                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16647                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16648                }
16649
16650                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16651                    if (userId != UserHandle.USER_OWNER) {
16652                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16653                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16654                        broadcastIntentLocked(null, null, intent, null,
16655                                new IIntentReceiver.Stub() {
16656                                    public void performReceive(Intent intent, int resultCode,
16657                                            String data, Bundle extras, boolean ordered,
16658                                            boolean sticky, int sendingUser) {
16659                                        userInitialized(uss, userId);
16660                                    }
16661                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16662                                true, false, MY_PID, Process.SYSTEM_UID,
16663                                userId);
16664                        uss.initializing = true;
16665                    } else {
16666                        getUserManagerLocked().makeInitialized(userInfo.id);
16667                    }
16668                }
16669
16670                if (foreground) {
16671                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16672                    if (homeInFront) {
16673                        startHomeActivityLocked(userId);
16674                    } else {
16675                        mStackSupervisor.resumeTopActivitiesLocked();
16676                    }
16677                    EventLogTags.writeAmSwitchUser(userId);
16678                    getUserManagerLocked().userForeground(userId);
16679                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16680                } else {
16681                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16682                }
16683
16684                if (needStart) {
16685                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16686                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16687                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16688                    broadcastIntentLocked(null, null, intent,
16689                            null, new IIntentReceiver.Stub() {
16690                                @Override
16691                                public void performReceive(Intent intent, int resultCode, String data,
16692                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16693                                        throws RemoteException {
16694                                }
16695                            }, 0, null, null,
16696                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16697                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16698                }
16699            }
16700        } finally {
16701            Binder.restoreCallingIdentity(ident);
16702        }
16703
16704        return true;
16705    }
16706
16707    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16708        long ident = Binder.clearCallingIdentity();
16709        try {
16710            Intent intent;
16711            if (oldUserId >= 0) {
16712                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16713                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16714                        | Intent.FLAG_RECEIVER_FOREGROUND);
16715                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16716                broadcastIntentLocked(null, null, intent,
16717                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16718                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16719            }
16720            if (newUserId >= 0) {
16721                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16722                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16723                        | Intent.FLAG_RECEIVER_FOREGROUND);
16724                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16725                broadcastIntentLocked(null, null, intent,
16726                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16727                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16728                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16729                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16730                        | Intent.FLAG_RECEIVER_FOREGROUND);
16731                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16732                broadcastIntentLocked(null, null, intent,
16733                        null, null, 0, null, null,
16734                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16735                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16736            }
16737        } finally {
16738            Binder.restoreCallingIdentity(ident);
16739        }
16740    }
16741
16742    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16743            final int newUserId) {
16744        final int N = mUserSwitchObservers.beginBroadcast();
16745        if (N > 0) {
16746            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16747                int mCount = 0;
16748                @Override
16749                public void sendResult(Bundle data) throws RemoteException {
16750                    synchronized (ActivityManagerService.this) {
16751                        if (mCurUserSwitchCallback == this) {
16752                            mCount++;
16753                            if (mCount == N) {
16754                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16755                            }
16756                        }
16757                    }
16758                }
16759            };
16760            synchronized (this) {
16761                uss.switching = true;
16762                mCurUserSwitchCallback = callback;
16763            }
16764            for (int i=0; i<N; i++) {
16765                try {
16766                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16767                            newUserId, callback);
16768                } catch (RemoteException e) {
16769                }
16770            }
16771        } else {
16772            synchronized (this) {
16773                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16774            }
16775        }
16776        mUserSwitchObservers.finishBroadcast();
16777    }
16778
16779    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16780        synchronized (this) {
16781            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16782            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16783        }
16784    }
16785
16786    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16787        mCurUserSwitchCallback = null;
16788        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16789        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16790                oldUserId, newUserId, uss));
16791    }
16792
16793    void userInitialized(UserStartedState uss, int newUserId) {
16794        completeSwitchAndInitalize(uss, newUserId, true, false);
16795    }
16796
16797    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16798        completeSwitchAndInitalize(uss, newUserId, false, true);
16799    }
16800
16801    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16802            boolean clearInitializing, boolean clearSwitching) {
16803        boolean unfrozen = false;
16804        synchronized (this) {
16805            if (clearInitializing) {
16806                uss.initializing = false;
16807                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16808            }
16809            if (clearSwitching) {
16810                uss.switching = false;
16811            }
16812            if (!uss.switching && !uss.initializing) {
16813                mWindowManager.stopFreezingScreen();
16814                unfrozen = true;
16815            }
16816        }
16817        if (unfrozen) {
16818            final int N = mUserSwitchObservers.beginBroadcast();
16819            for (int i=0; i<N; i++) {
16820                try {
16821                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16822                } catch (RemoteException e) {
16823                }
16824            }
16825            mUserSwitchObservers.finishBroadcast();
16826        }
16827    }
16828
16829    void scheduleStartProfilesLocked() {
16830        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16831            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16832                    DateUtils.SECOND_IN_MILLIS);
16833        }
16834    }
16835
16836    void startProfilesLocked() {
16837        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16838        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16839                mCurrentUserId, false /* enabledOnly */);
16840        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16841        for (UserInfo user : profiles) {
16842            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16843                    && user.id != mCurrentUserId) {
16844                toStart.add(user);
16845            }
16846        }
16847        final int n = toStart.size();
16848        int i = 0;
16849        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16850            startUserInBackground(toStart.get(i).id);
16851        }
16852        if (i < n) {
16853            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16854        }
16855    }
16856
16857    void finishUserBoot(UserStartedState uss) {
16858        synchronized (this) {
16859            if (uss.mState == UserStartedState.STATE_BOOTING
16860                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16861                uss.mState = UserStartedState.STATE_RUNNING;
16862                final int userId = uss.mHandle.getIdentifier();
16863                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16864                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16865                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16866                broadcastIntentLocked(null, null, intent,
16867                        null, null, 0, null, null,
16868                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16869                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16870            }
16871        }
16872    }
16873
16874    void finishUserSwitch(UserStartedState uss) {
16875        synchronized (this) {
16876            finishUserBoot(uss);
16877
16878            startProfilesLocked();
16879
16880            int num = mUserLru.size();
16881            int i = 0;
16882            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16883                Integer oldUserId = mUserLru.get(i);
16884                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16885                if (oldUss == null) {
16886                    // Shouldn't happen, but be sane if it does.
16887                    mUserLru.remove(i);
16888                    num--;
16889                    continue;
16890                }
16891                if (oldUss.mState == UserStartedState.STATE_STOPPING
16892                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16893                    // This user is already stopping, doesn't count.
16894                    num--;
16895                    i++;
16896                    continue;
16897                }
16898                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16899                    // Owner and current can't be stopped, but count as running.
16900                    i++;
16901                    continue;
16902                }
16903                // This is a user to be stopped.
16904                stopUserLocked(oldUserId, null);
16905                num--;
16906                i++;
16907            }
16908        }
16909    }
16910
16911    @Override
16912    public int stopUser(final int userId, final IStopUserCallback callback) {
16913        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16914                != PackageManager.PERMISSION_GRANTED) {
16915            String msg = "Permission Denial: switchUser() from pid="
16916                    + Binder.getCallingPid()
16917                    + ", uid=" + Binder.getCallingUid()
16918                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16919            Slog.w(TAG, msg);
16920            throw new SecurityException(msg);
16921        }
16922        if (userId <= 0) {
16923            throw new IllegalArgumentException("Can't stop primary user " + userId);
16924        }
16925        synchronized (this) {
16926            return stopUserLocked(userId, callback);
16927        }
16928    }
16929
16930    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16931        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16932        if (mCurrentUserId == userId) {
16933            return ActivityManager.USER_OP_IS_CURRENT;
16934        }
16935
16936        final UserStartedState uss = mStartedUsers.get(userId);
16937        if (uss == null) {
16938            // User is not started, nothing to do...  but we do need to
16939            // callback if requested.
16940            if (callback != null) {
16941                mHandler.post(new Runnable() {
16942                    @Override
16943                    public void run() {
16944                        try {
16945                            callback.userStopped(userId);
16946                        } catch (RemoteException e) {
16947                        }
16948                    }
16949                });
16950            }
16951            return ActivityManager.USER_OP_SUCCESS;
16952        }
16953
16954        if (callback != null) {
16955            uss.mStopCallbacks.add(callback);
16956        }
16957
16958        if (uss.mState != UserStartedState.STATE_STOPPING
16959                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16960            uss.mState = UserStartedState.STATE_STOPPING;
16961            updateStartedUserArrayLocked();
16962
16963            long ident = Binder.clearCallingIdentity();
16964            try {
16965                // We are going to broadcast ACTION_USER_STOPPING and then
16966                // once that is done send a final ACTION_SHUTDOWN and then
16967                // stop the user.
16968                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16969                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16970                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16971                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16972                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16973                // This is the result receiver for the final shutdown broadcast.
16974                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16975                    @Override
16976                    public void performReceive(Intent intent, int resultCode, String data,
16977                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16978                        finishUserStop(uss);
16979                    }
16980                };
16981                // This is the result receiver for the initial stopping broadcast.
16982                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16983                    @Override
16984                    public void performReceive(Intent intent, int resultCode, String data,
16985                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16986                        // On to the next.
16987                        synchronized (ActivityManagerService.this) {
16988                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16989                                // Whoops, we are being started back up.  Abort, abort!
16990                                return;
16991                            }
16992                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16993                        }
16994                        mSystemServiceManager.stopUser(userId);
16995                        broadcastIntentLocked(null, null, shutdownIntent,
16996                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16997                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16998                    }
16999                };
17000                // Kick things off.
17001                broadcastIntentLocked(null, null, stoppingIntent,
17002                        null, stoppingReceiver, 0, null, null,
17003                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17004                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17005            } finally {
17006                Binder.restoreCallingIdentity(ident);
17007            }
17008        }
17009
17010        return ActivityManager.USER_OP_SUCCESS;
17011    }
17012
17013    void finishUserStop(UserStartedState uss) {
17014        final int userId = uss.mHandle.getIdentifier();
17015        boolean stopped;
17016        ArrayList<IStopUserCallback> callbacks;
17017        synchronized (this) {
17018            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17019            if (mStartedUsers.get(userId) != uss) {
17020                stopped = false;
17021            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17022                stopped = false;
17023            } else {
17024                stopped = true;
17025                // User can no longer run.
17026                mStartedUsers.remove(userId);
17027                mUserLru.remove(Integer.valueOf(userId));
17028                updateStartedUserArrayLocked();
17029
17030                // Clean up all state and processes associated with the user.
17031                // Kill all the processes for the user.
17032                forceStopUserLocked(userId, "finish user");
17033            }
17034        }
17035
17036        for (int i=0; i<callbacks.size(); i++) {
17037            try {
17038                if (stopped) callbacks.get(i).userStopped(userId);
17039                else callbacks.get(i).userStopAborted(userId);
17040            } catch (RemoteException e) {
17041            }
17042        }
17043
17044        if (stopped) {
17045            mSystemServiceManager.cleanupUser(userId);
17046            synchronized (this) {
17047                mStackSupervisor.removeUserLocked(userId);
17048            }
17049        }
17050    }
17051
17052    @Override
17053    public UserInfo getCurrentUser() {
17054        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17055                != PackageManager.PERMISSION_GRANTED) && (
17056                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17057                != PackageManager.PERMISSION_GRANTED)) {
17058            String msg = "Permission Denial: getCurrentUser() from pid="
17059                    + Binder.getCallingPid()
17060                    + ", uid=" + Binder.getCallingUid()
17061                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17062            Slog.w(TAG, msg);
17063            throw new SecurityException(msg);
17064        }
17065        synchronized (this) {
17066            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17067        }
17068    }
17069
17070    int getCurrentUserIdLocked() {
17071        return mCurrentUserId;
17072    }
17073
17074    @Override
17075    public boolean isUserRunning(int userId, boolean orStopped) {
17076        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17077                != PackageManager.PERMISSION_GRANTED) {
17078            String msg = "Permission Denial: isUserRunning() from pid="
17079                    + Binder.getCallingPid()
17080                    + ", uid=" + Binder.getCallingUid()
17081                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17082            Slog.w(TAG, msg);
17083            throw new SecurityException(msg);
17084        }
17085        synchronized (this) {
17086            return isUserRunningLocked(userId, orStopped);
17087        }
17088    }
17089
17090    boolean isUserRunningLocked(int userId, boolean orStopped) {
17091        UserStartedState state = mStartedUsers.get(userId);
17092        if (state == null) {
17093            return false;
17094        }
17095        if (orStopped) {
17096            return true;
17097        }
17098        return state.mState != UserStartedState.STATE_STOPPING
17099                && state.mState != UserStartedState.STATE_SHUTDOWN;
17100    }
17101
17102    @Override
17103    public int[] getRunningUserIds() {
17104        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17105                != PackageManager.PERMISSION_GRANTED) {
17106            String msg = "Permission Denial: isUserRunning() from pid="
17107                    + Binder.getCallingPid()
17108                    + ", uid=" + Binder.getCallingUid()
17109                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17110            Slog.w(TAG, msg);
17111            throw new SecurityException(msg);
17112        }
17113        synchronized (this) {
17114            return mStartedUserArray;
17115        }
17116    }
17117
17118    private void updateStartedUserArrayLocked() {
17119        int num = 0;
17120        for (int i=0; i<mStartedUsers.size();  i++) {
17121            UserStartedState uss = mStartedUsers.valueAt(i);
17122            // This list does not include stopping users.
17123            if (uss.mState != UserStartedState.STATE_STOPPING
17124                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17125                num++;
17126            }
17127        }
17128        mStartedUserArray = new int[num];
17129        num = 0;
17130        for (int i=0; i<mStartedUsers.size();  i++) {
17131            UserStartedState uss = mStartedUsers.valueAt(i);
17132            if (uss.mState != UserStartedState.STATE_STOPPING
17133                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17134                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17135                num++;
17136            }
17137        }
17138    }
17139
17140    @Override
17141    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17142        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17143                != PackageManager.PERMISSION_GRANTED) {
17144            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17145                    + Binder.getCallingPid()
17146                    + ", uid=" + Binder.getCallingUid()
17147                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17148            Slog.w(TAG, msg);
17149            throw new SecurityException(msg);
17150        }
17151
17152        mUserSwitchObservers.register(observer);
17153    }
17154
17155    @Override
17156    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17157        mUserSwitchObservers.unregister(observer);
17158    }
17159
17160    private boolean userExists(int userId) {
17161        if (userId == 0) {
17162            return true;
17163        }
17164        UserManagerService ums = getUserManagerLocked();
17165        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17166    }
17167
17168    int[] getUsersLocked() {
17169        UserManagerService ums = getUserManagerLocked();
17170        return ums != null ? ums.getUserIds() : new int[] { 0 };
17171    }
17172
17173    UserManagerService getUserManagerLocked() {
17174        if (mUserManager == null) {
17175            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17176            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17177        }
17178        return mUserManager;
17179    }
17180
17181    private int applyUserId(int uid, int userId) {
17182        return UserHandle.getUid(userId, uid);
17183    }
17184
17185    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17186        if (info == null) return null;
17187        ApplicationInfo newInfo = new ApplicationInfo(info);
17188        newInfo.uid = applyUserId(info.uid, userId);
17189        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17190                + info.packageName;
17191        return newInfo;
17192    }
17193
17194    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17195        if (aInfo == null
17196                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17197            return aInfo;
17198        }
17199
17200        ActivityInfo info = new ActivityInfo(aInfo);
17201        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17202        return info;
17203    }
17204
17205    private final class LocalService extends ActivityManagerInternal {
17206        @Override
17207        public void goingToSleep() {
17208            ActivityManagerService.this.goingToSleep();
17209        }
17210
17211        @Override
17212        public void wakingUp() {
17213            ActivityManagerService.this.wakingUp();
17214        }
17215    }
17216
17217    /**
17218     * An implementation of IAppTask, that allows an app to manage its own tasks via
17219     * {@link android.app.ActivityManager#AppTask}.  We keep track of the callingUid to ensure that
17220     * only the process that calls getAppTasks() can call the AppTask methods.
17221     */
17222    class AppTaskImpl extends IAppTask.Stub {
17223        private int mTaskId;
17224        private int mCallingUid;
17225
17226        public AppTaskImpl(int taskId, int callingUid) {
17227            mTaskId = taskId;
17228            mCallingUid = callingUid;
17229        }
17230
17231        @Override
17232        public void finishAndRemoveTask() {
17233            // Ensure that we are called from the same process that created this AppTask
17234            if (mCallingUid != Binder.getCallingUid()) {
17235                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17236                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17237                return;
17238            }
17239
17240            synchronized (ActivityManagerService.this) {
17241                long origId = Binder.clearCallingIdentity();
17242                try {
17243                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17244                    if (tr != null) {
17245                        // Only kill the process if we are not a new document
17246                        int flags = tr.getBaseIntent().getFlags();
17247                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17248                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17249                        removeTaskByIdLocked(mTaskId,
17250                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17251                    }
17252                } finally {
17253                    Binder.restoreCallingIdentity(origId);
17254                }
17255            }
17256        }
17257
17258        @Override
17259        public ActivityManager.RecentTaskInfo getTaskInfo() {
17260            // Ensure that we are called from the same process that created this AppTask
17261            if (mCallingUid != Binder.getCallingUid()) {
17262                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17263                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17264                return null;
17265            }
17266
17267            synchronized (ActivityManagerService.this) {
17268                long origId = Binder.clearCallingIdentity();
17269                try {
17270                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17271                    if (tr != null) {
17272                        return createRecentTaskInfoFromTaskRecord(tr);
17273                    }
17274                } finally {
17275                    Binder.restoreCallingIdentity(origId);
17276                }
17277                return null;
17278            }
17279        }
17280    }
17281}
17282