ActivityManagerService.java revision ffcfcaadfefec2fb56f67a0a614a54bf4599d62b
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.app.admin.DevicePolicyManager;
37import android.appwidget.AppWidgetManager;
38import android.graphics.Rect;
39import android.os.BatteryStats;
40import android.os.PersistableBundle;
41import android.service.voice.IVoiceInteractionSession;
42import android.util.ArrayMap;
43
44import com.android.internal.R;
45import com.android.internal.annotations.GuardedBy;
46import com.android.internal.app.IAppOpsService;
47import com.android.internal.app.IVoiceInteractor;
48import com.android.internal.app.ProcessMap;
49import com.android.internal.app.ProcessStats;
50import com.android.internal.content.PackageMonitor;
51import com.android.internal.os.BackgroundThread;
52import com.android.internal.os.BatteryStatsImpl;
53import com.android.internal.os.ProcessCpuTracker;
54import com.android.internal.os.TransferPipe;
55import com.android.internal.os.Zygote;
56import com.android.internal.util.FastPrintWriter;
57import com.android.internal.util.FastXmlSerializer;
58import com.android.internal.util.MemInfoReader;
59import com.android.internal.util.Preconditions;
60import com.android.server.AppOpsService;
61import com.android.server.AttributeCache;
62import com.android.server.IntentResolver;
63import com.android.server.LocalServices;
64import com.android.server.ServiceThread;
65import com.android.server.SystemService;
66import com.android.server.SystemServiceManager;
67import com.android.server.Watchdog;
68import com.android.server.am.ActivityStack.ActivityState;
69import com.android.server.firewall.IntentFirewall;
70import com.android.server.pm.UserManagerService;
71import com.android.server.wm.AppTransition;
72import com.android.server.wm.WindowManagerService;
73import com.google.android.collect.Lists;
74import com.google.android.collect.Maps;
75
76import libcore.io.IoUtils;
77
78import org.xmlpull.v1.XmlPullParser;
79import org.xmlpull.v1.XmlPullParserException;
80import org.xmlpull.v1.XmlSerializer;
81
82import android.app.Activity;
83import android.app.ActivityManager;
84import android.app.ActivityManager.RunningTaskInfo;
85import android.app.ActivityManager.StackInfo;
86import android.app.ActivityManagerInternal;
87import android.app.ActivityManagerNative;
88import android.app.ActivityOptions;
89import android.app.ActivityThread;
90import android.app.AlertDialog;
91import android.app.AppGlobals;
92import android.app.ApplicationErrorReport;
93import android.app.Dialog;
94import android.app.IActivityController;
95import android.app.IApplicationThread;
96import android.app.IInstrumentationWatcher;
97import android.app.INotificationManager;
98import android.app.IProcessObserver;
99import android.app.IServiceConnection;
100import android.app.IStopUserCallback;
101import android.app.IUiAutomationConnection;
102import android.app.IUserSwitchObserver;
103import android.app.Instrumentation;
104import android.app.Notification;
105import android.app.NotificationManager;
106import android.app.PendingIntent;
107import android.app.backup.IBackupManager;
108import android.content.ActivityNotFoundException;
109import android.content.BroadcastReceiver;
110import android.content.ClipData;
111import android.content.ComponentCallbacks2;
112import android.content.ComponentName;
113import android.content.ContentProvider;
114import android.content.ContentResolver;
115import android.content.Context;
116import android.content.DialogInterface;
117import android.content.IContentProvider;
118import android.content.IIntentReceiver;
119import android.content.IIntentSender;
120import android.content.Intent;
121import android.content.IntentFilter;
122import android.content.IntentSender;
123import android.content.pm.ActivityInfo;
124import android.content.pm.ApplicationInfo;
125import android.content.pm.ConfigurationInfo;
126import android.content.pm.IPackageDataObserver;
127import android.content.pm.IPackageManager;
128import android.content.pm.InstrumentationInfo;
129import android.content.pm.PackageInfo;
130import android.content.pm.PackageManager;
131import android.content.pm.ParceledListSlice;
132import android.content.pm.UserInfo;
133import android.content.pm.PackageManager.NameNotFoundException;
134import android.content.pm.PathPermission;
135import android.content.pm.ProviderInfo;
136import android.content.pm.ResolveInfo;
137import android.content.pm.ServiceInfo;
138import android.content.res.CompatibilityInfo;
139import android.content.res.Configuration;
140import android.graphics.Bitmap;
141import android.net.Proxy;
142import android.net.ProxyInfo;
143import android.net.Uri;
144import android.os.Binder;
145import android.os.Build;
146import android.os.Bundle;
147import android.os.Debug;
148import android.os.DropBoxManager;
149import android.os.Environment;
150import android.os.FactoryTest;
151import android.os.FileObserver;
152import android.os.FileUtils;
153import android.os.Handler;
154import android.os.IBinder;
155import android.os.IPermissionController;
156import android.os.IRemoteCallback;
157import android.os.IUserManager;
158import android.os.Looper;
159import android.os.Message;
160import android.os.Parcel;
161import android.os.ParcelFileDescriptor;
162import android.os.Process;
163import android.os.RemoteCallbackList;
164import android.os.RemoteException;
165import android.os.SELinux;
166import android.os.ServiceManager;
167import android.os.StrictMode;
168import android.os.SystemClock;
169import android.os.SystemProperties;
170import android.os.UpdateLock;
171import android.os.UserHandle;
172import android.provider.Settings;
173import android.text.format.DateUtils;
174import android.text.format.Time;
175import android.util.AtomicFile;
176import android.util.EventLog;
177import android.util.Log;
178import android.util.Pair;
179import android.util.PrintWriterPrinter;
180import android.util.Slog;
181import android.util.SparseArray;
182import android.util.TimeUtils;
183import android.util.Xml;
184import android.view.Gravity;
185import android.view.LayoutInflater;
186import android.view.View;
187import android.view.WindowManager;
188
189import java.io.BufferedInputStream;
190import java.io.BufferedOutputStream;
191import java.io.DataInputStream;
192import java.io.DataOutputStream;
193import java.io.File;
194import java.io.FileDescriptor;
195import java.io.FileInputStream;
196import java.io.FileNotFoundException;
197import java.io.FileOutputStream;
198import java.io.IOException;
199import java.io.InputStreamReader;
200import java.io.PrintWriter;
201import java.io.StringWriter;
202import java.lang.ref.WeakReference;
203import java.util.ArrayList;
204import java.util.Arrays;
205import java.util.Collections;
206import java.util.Comparator;
207import java.util.HashMap;
208import java.util.HashSet;
209import java.util.Iterator;
210import java.util.List;
211import java.util.Locale;
212import java.util.Map;
213import java.util.Set;
214import java.util.concurrent.atomic.AtomicBoolean;
215import java.util.concurrent.atomic.AtomicLong;
216
217public final class ActivityManagerService extends ActivityManagerNative
218        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
219    private static final String USER_DATA_DIR = "/data/user/";
220    static final String TAG = "ActivityManager";
221    static final String TAG_MU = "ActivityManagerServiceMU";
222    static final boolean DEBUG = false;
223    static final boolean localLOGV = DEBUG;
224    static final boolean DEBUG_BACKUP = localLOGV || false;
225    static final boolean DEBUG_BROADCAST = localLOGV || false;
226    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
227    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_CLEANUP = localLOGV || false;
229    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
230    static final boolean DEBUG_FOCUS = false;
231    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
232    static final boolean DEBUG_MU = localLOGV || false;
233    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
234    static final boolean DEBUG_LRU = localLOGV || false;
235    static final boolean DEBUG_PAUSE = localLOGV || false;
236    static final boolean DEBUG_POWER = localLOGV || false;
237    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
238    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
239    static final boolean DEBUG_PROCESSES = localLOGV || false;
240    static final boolean DEBUG_PROVIDER = localLOGV || false;
241    static final boolean DEBUG_RESULTS = localLOGV || false;
242    static final boolean DEBUG_SERVICE = localLOGV || false;
243    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
244    static final boolean DEBUG_STACK = localLOGV || false;
245    static final boolean DEBUG_SWITCH = localLOGV || false;
246    static final boolean DEBUG_TASKS = localLOGV || false;
247    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
248    static final boolean DEBUG_TRANSITION = localLOGV || false;
249    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
250    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
251    static final boolean DEBUG_VISBILITY = localLOGV || false;
252    static final boolean DEBUG_PSS = localLOGV || false;
253    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
254    static final boolean VALIDATE_TOKENS = false;
255    static final boolean SHOW_ACTIVITY_START_TIME = true;
256
257    // Control over CPU and battery monitoring.
258    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
259    static final boolean MONITOR_CPU_USAGE = true;
260    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
261    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
262    static final boolean MONITOR_THREAD_CPU_USAGE = false;
263
264    // The flags that are set for all calls we make to the package manager.
265    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
266
267    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
268
269    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
270
271    // Maximum number of recent tasks that we can remember.
272    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200;
273
274    // Amount of time after a call to stopAppSwitches() during which we will
275    // prevent further untrusted switches from happening.
276    static final long APP_SWITCH_DELAY_TIME = 5*1000;
277
278    // How long we wait for a launched process to attach to the activity manager
279    // before we decide it's never going to come up for real.
280    static final int PROC_START_TIMEOUT = 10*1000;
281
282    // How long we wait for a launched process to attach to the activity manager
283    // before we decide it's never going to come up for real, when the process was
284    // started with a wrapper for instrumentation (such as Valgrind) because it
285    // could take much longer than usual.
286    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
287
288    // How long to wait after going idle before forcing apps to GC.
289    static final int GC_TIMEOUT = 5*1000;
290
291    // The minimum amount of time between successive GC requests for a process.
292    static final int GC_MIN_INTERVAL = 60*1000;
293
294    // The minimum amount of time between successive PSS requests for a process.
295    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
296
297    // The minimum amount of time between successive PSS requests for a process
298    // when the request is due to the memory state being lowered.
299    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
300
301    // The rate at which we check for apps using excessive power -- 15 mins.
302    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
303
304    // The minimum sample duration we will allow before deciding we have
305    // enough data on wake locks to start killing things.
306    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
307
308    // The minimum sample duration we will allow before deciding we have
309    // enough data on CPU usage to start killing things.
310    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
311
312    // How long we allow a receiver to run before giving up on it.
313    static final int BROADCAST_FG_TIMEOUT = 10*1000;
314    static final int BROADCAST_BG_TIMEOUT = 60*1000;
315
316    // How long we wait until we timeout on key dispatching.
317    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
318
319    // How long we wait until we timeout on key dispatching during instrumentation.
320    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
321
322    // Amount of time we wait for observers to handle a user switch before
323    // giving up on them and unfreezing the screen.
324    static final int USER_SWITCH_TIMEOUT = 2*1000;
325
326    // Maximum number of users we allow to be running at a time.
327    static final int MAX_RUNNING_USERS = 3;
328
329    // How long to wait in getAssistContextExtras for the activity and foreground services
330    // to respond with the result.
331    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
332
333    // Maximum number of persisted Uri grants a package is allowed
334    static final int MAX_PERSISTED_URI_GRANTS = 128;
335
336    static final int MY_PID = Process.myPid();
337
338    static final String[] EMPTY_STRING_ARRAY = new String[0];
339
340    // How many bytes to write into the dropbox log before truncating
341    static final int DROPBOX_MAX_SIZE = 256 * 1024;
342
343    /** All system services */
344    SystemServiceManager mSystemServiceManager;
345
346    /** Run all ActivityStacks through this */
347    ActivityStackSupervisor mStackSupervisor;
348
349    public IntentFirewall mIntentFirewall;
350
351    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
352    // default actuion automatically.  Important for devices without direct input
353    // devices.
354    private boolean mShowDialogs = true;
355
356    /**
357     * Description of a request to start a new activity, which has been held
358     * due to app switches being disabled.
359     */
360    static class PendingActivityLaunch {
361        final ActivityRecord r;
362        final ActivityRecord sourceRecord;
363        final int startFlags;
364        final ActivityStack stack;
365
366        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
367                int _startFlags, ActivityStack _stack) {
368            r = _r;
369            sourceRecord = _sourceRecord;
370            startFlags = _startFlags;
371            stack = _stack;
372        }
373    }
374
375    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
376            = new ArrayList<PendingActivityLaunch>();
377
378    BroadcastQueue mFgBroadcastQueue;
379    BroadcastQueue mBgBroadcastQueue;
380    // Convenient for easy iteration over the queues. Foreground is first
381    // so that dispatch of foreground broadcasts gets precedence.
382    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
383
384    BroadcastQueue broadcastQueueForIntent(Intent intent) {
385        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
386        if (DEBUG_BACKGROUND_BROADCAST) {
387            Slog.i(TAG, "Broadcast intent " + intent + " on "
388                    + (isFg ? "foreground" : "background")
389                    + " queue");
390        }
391        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
392    }
393
394    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
395        for (BroadcastQueue queue : mBroadcastQueues) {
396            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
397            if (r != null) {
398                return r;
399            }
400        }
401        return null;
402    }
403
404    /**
405     * Activity we have told the window manager to have key focus.
406     */
407    ActivityRecord mFocusedActivity = null;
408
409    /**
410     * List of intents that were used to start the most recent tasks.
411     */
412    ArrayList<TaskRecord> mRecentTasks;
413
414    public class PendingAssistExtras extends Binder implements Runnable {
415        public final ActivityRecord activity;
416        public boolean haveResult = false;
417        public Bundle result = null;
418        public PendingAssistExtras(ActivityRecord _activity) {
419            activity = _activity;
420        }
421        @Override
422        public void run() {
423            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
424            synchronized (this) {
425                haveResult = true;
426                notifyAll();
427            }
428        }
429    }
430
431    final ArrayList<PendingAssistExtras> mPendingAssistExtras
432            = new ArrayList<PendingAssistExtras>();
433
434    /**
435     * Process management.
436     */
437    final ProcessList mProcessList = new ProcessList();
438
439    /**
440     * All of the applications we currently have running organized by name.
441     * The keys are strings of the application package name (as
442     * returned by the package manager), and the keys are ApplicationRecord
443     * objects.
444     */
445    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
446
447    /**
448     * Tracking long-term execution of processes to look for abuse and other
449     * bad app behavior.
450     */
451    final ProcessStatsService mProcessStats;
452
453    /**
454     * The currently running isolated processes.
455     */
456    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
457
458    /**
459     * Counter for assigning isolated process uids, to avoid frequently reusing the
460     * same ones.
461     */
462    int mNextIsolatedProcessUid = 0;
463
464    /**
465     * The currently running heavy-weight process, if any.
466     */
467    ProcessRecord mHeavyWeightProcess = null;
468
469    /**
470     * The last time that various processes have crashed.
471     */
472    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
473
474    /**
475     * Information about a process that is currently marked as bad.
476     */
477    static final class BadProcessInfo {
478        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
479            this.time = time;
480            this.shortMsg = shortMsg;
481            this.longMsg = longMsg;
482            this.stack = stack;
483        }
484
485        final long time;
486        final String shortMsg;
487        final String longMsg;
488        final String stack;
489    }
490
491    /**
492     * Set of applications that we consider to be bad, and will reject
493     * incoming broadcasts from (which the user has no control over).
494     * Processes are added to this set when they have crashed twice within
495     * a minimum amount of time; they are removed from it when they are
496     * later restarted (hopefully due to some user action).  The value is the
497     * time it was added to the list.
498     */
499    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
500
501    /**
502     * All of the processes we currently have running organized by pid.
503     * The keys are the pid running the application.
504     *
505     * <p>NOTE: This object is protected by its own lock, NOT the global
506     * activity manager lock!
507     */
508    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
509
510    /**
511     * All of the processes that have been forced to be foreground.  The key
512     * is the pid of the caller who requested it (we hold a death
513     * link on it).
514     */
515    abstract class ForegroundToken implements IBinder.DeathRecipient {
516        int pid;
517        IBinder token;
518    }
519    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
520
521    /**
522     * List of records for processes that someone had tried to start before the
523     * system was ready.  We don't start them at that point, but ensure they
524     * are started by the time booting is complete.
525     */
526    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
527
528    /**
529     * List of persistent applications that are in the process
530     * of being started.
531     */
532    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
533
534    /**
535     * Processes that are being forcibly torn down.
536     */
537    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
538
539    /**
540     * List of running applications, sorted by recent usage.
541     * The first entry in the list is the least recently used.
542     */
543    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
544
545    /**
546     * Where in mLruProcesses that the processes hosting activities start.
547     */
548    int mLruProcessActivityStart = 0;
549
550    /**
551     * Where in mLruProcesses that the processes hosting services start.
552     * This is after (lower index) than mLruProcessesActivityStart.
553     */
554    int mLruProcessServiceStart = 0;
555
556    /**
557     * List of processes that should gc as soon as things are idle.
558     */
559    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
560
561    /**
562     * Processes we want to collect PSS data from.
563     */
564    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
565
566    /**
567     * Last time we requested PSS data of all processes.
568     */
569    long mLastFullPssTime = SystemClock.uptimeMillis();
570
571    /**
572     * This is the process holding what we currently consider to be
573     * the "home" activity.
574     */
575    ProcessRecord mHomeProcess;
576
577    /**
578     * This is the process holding the activity the user last visited that
579     * is in a different process from the one they are currently in.
580     */
581    ProcessRecord mPreviousProcess;
582
583    /**
584     * The time at which the previous process was last visible.
585     */
586    long mPreviousProcessVisibleTime;
587
588    /**
589     * Which uses have been started, so are allowed to run code.
590     */
591    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
592
593    /**
594     * LRU list of history of current users.  Most recently current is at the end.
595     */
596    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
597
598    /**
599     * Constant array of the users that are currently started.
600     */
601    int[] mStartedUserArray = new int[] { 0 };
602
603    /**
604     * Registered observers of the user switching mechanics.
605     */
606    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
607            = new RemoteCallbackList<IUserSwitchObserver>();
608
609    /**
610     * Currently active user switch.
611     */
612    Object mCurUserSwitchCallback;
613
614    /**
615     * Packages that the user has asked to have run in screen size
616     * compatibility mode instead of filling the screen.
617     */
618    final CompatModePackages mCompatModePackages;
619
620    /**
621     * Set of IntentSenderRecord objects that are currently active.
622     */
623    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
624            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
625
626    /**
627     * Fingerprints (hashCode()) of stack traces that we've
628     * already logged DropBox entries for.  Guarded by itself.  If
629     * something (rogue user app) forces this over
630     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
631     */
632    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
633    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
634
635    /**
636     * Strict Mode background batched logging state.
637     *
638     * The string buffer is guarded by itself, and its lock is also
639     * used to determine if another batched write is already
640     * in-flight.
641     */
642    private final StringBuilder mStrictModeBuffer = new StringBuilder();
643
644    /**
645     * Keeps track of all IIntentReceivers that have been registered for
646     * broadcasts.  Hash keys are the receiver IBinder, hash value is
647     * a ReceiverList.
648     */
649    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
650            new HashMap<IBinder, ReceiverList>();
651
652    /**
653     * Resolver for broadcast intents to registered receivers.
654     * Holds BroadcastFilter (subclass of IntentFilter).
655     */
656    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
657            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
658        @Override
659        protected boolean allowFilterResult(
660                BroadcastFilter filter, List<BroadcastFilter> dest) {
661            IBinder target = filter.receiverList.receiver.asBinder();
662            for (int i=dest.size()-1; i>=0; i--) {
663                if (dest.get(i).receiverList.receiver.asBinder() == target) {
664                    return false;
665                }
666            }
667            return true;
668        }
669
670        @Override
671        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
672            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
673                    || userId == filter.owningUserId) {
674                return super.newResult(filter, match, userId);
675            }
676            return null;
677        }
678
679        @Override
680        protected BroadcastFilter[] newArray(int size) {
681            return new BroadcastFilter[size];
682        }
683
684        @Override
685        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
686            return packageName.equals(filter.packageName);
687        }
688    };
689
690    /**
691     * State of all active sticky broadcasts per user.  Keys are the action of the
692     * sticky Intent, values are an ArrayList of all broadcasted intents with
693     * that action (which should usually be one).  The SparseArray is keyed
694     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
695     * for stickies that are sent to all users.
696     */
697    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
698            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
699
700    final ActiveServices mServices;
701
702    /**
703     * Backup/restore process management
704     */
705    String mBackupAppName = null;
706    BackupRecord mBackupTarget = null;
707
708    final ProviderMap mProviderMap;
709
710    /**
711     * List of content providers who have clients waiting for them.  The
712     * application is currently being launched and the provider will be
713     * removed from this list once it is published.
714     */
715    final ArrayList<ContentProviderRecord> mLaunchingProviders
716            = new ArrayList<ContentProviderRecord>();
717
718    /**
719     * File storing persisted {@link #mGrantedUriPermissions}.
720     */
721    private final AtomicFile mGrantFile;
722
723    /** XML constants used in {@link #mGrantFile} */
724    private static final String TAG_URI_GRANTS = "uri-grants";
725    private static final String TAG_URI_GRANT = "uri-grant";
726    private static final String ATTR_USER_HANDLE = "userHandle";
727    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
728    private static final String ATTR_TARGET_USER_ID = "targetUserId";
729    private static final String ATTR_SOURCE_PKG = "sourcePkg";
730    private static final String ATTR_TARGET_PKG = "targetPkg";
731    private static final String ATTR_URI = "uri";
732    private static final String ATTR_MODE_FLAGS = "modeFlags";
733    private static final String ATTR_CREATED_TIME = "createdTime";
734    private static final String ATTR_PREFIX = "prefix";
735
736    /**
737     * Global set of specific {@link Uri} permissions that have been granted.
738     * This optimized lookup structure maps from {@link UriPermission#targetUid}
739     * to {@link UriPermission#uri} to {@link UriPermission}.
740     */
741    @GuardedBy("this")
742    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
743            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
744
745    public static class GrantUri {
746        public final int sourceUserId;
747        public final Uri uri;
748        public boolean prefix;
749
750        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
751            this.sourceUserId = sourceUserId;
752            this.uri = uri;
753            this.prefix = prefix;
754        }
755
756        @Override
757        public int hashCode() {
758            return toString().hashCode();
759        }
760
761        @Override
762        public boolean equals(Object o) {
763            if (o instanceof GrantUri) {
764                GrantUri other = (GrantUri) o;
765                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
766                        && prefix == other.prefix;
767            }
768            return false;
769        }
770
771        @Override
772        public String toString() {
773            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
774            if (prefix) result += " [prefix]";
775            return result;
776        }
777
778        public String toSafeString() {
779            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
780            if (prefix) result += " [prefix]";
781            return result;
782        }
783
784        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
785            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
786                    ContentProvider.getUriWithoutUserId(uri), false);
787        }
788    }
789
790    CoreSettingsObserver mCoreSettingsObserver;
791
792    /**
793     * Thread-local storage used to carry caller permissions over through
794     * indirect content-provider access.
795     */
796    private class Identity {
797        public int pid;
798        public int uid;
799
800        Identity(int _pid, int _uid) {
801            pid = _pid;
802            uid = _uid;
803        }
804    }
805
806    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
807
808    /**
809     * All information we have collected about the runtime performance of
810     * any user id that can impact battery performance.
811     */
812    final BatteryStatsService mBatteryStatsService;
813
814    /**
815     * Information about component usage
816     */
817    final UsageStatsService mUsageStatsService;
818
819    /**
820     * Information about and control over application operations
821     */
822    final AppOpsService mAppOpsService;
823
824    /**
825     * Save recent tasks information across reboots.
826     */
827    final TaskPersister mTaskPersister;
828
829    /**
830     * Current configuration information.  HistoryRecord objects are given
831     * a reference to this object to indicate which configuration they are
832     * currently running in, so this object must be kept immutable.
833     */
834    Configuration mConfiguration = new Configuration();
835
836    /**
837     * Current sequencing integer of the configuration, for skipping old
838     * configurations.
839     */
840    int mConfigurationSeq = 0;
841
842    /**
843     * Hardware-reported OpenGLES version.
844     */
845    final int GL_ES_VERSION;
846
847    /**
848     * List of initialization arguments to pass to all processes when binding applications to them.
849     * For example, references to the commonly used services.
850     */
851    HashMap<String, IBinder> mAppBindArgs;
852
853    /**
854     * Temporary to avoid allocations.  Protected by main lock.
855     */
856    final StringBuilder mStringBuilder = new StringBuilder(256);
857
858    /**
859     * Used to control how we initialize the service.
860     */
861    ComponentName mTopComponent;
862    String mTopAction = Intent.ACTION_MAIN;
863    String mTopData;
864    boolean mProcessesReady = false;
865    boolean mSystemReady = false;
866    boolean mBooting = false;
867    boolean mWaitingUpdate = false;
868    boolean mDidUpdate = false;
869    boolean mOnBattery = false;
870    boolean mLaunchWarningShown = false;
871
872    Context mContext;
873
874    int mFactoryTest;
875
876    boolean mCheckedForSetup;
877
878    /**
879     * The time at which we will allow normal application switches again,
880     * after a call to {@link #stopAppSwitches()}.
881     */
882    long mAppSwitchesAllowedTime;
883
884    /**
885     * This is set to true after the first switch after mAppSwitchesAllowedTime
886     * is set; any switches after that will clear the time.
887     */
888    boolean mDidAppSwitch;
889
890    /**
891     * Last time (in realtime) at which we checked for power usage.
892     */
893    long mLastPowerCheckRealtime;
894
895    /**
896     * Last time (in uptime) at which we checked for power usage.
897     */
898    long mLastPowerCheckUptime;
899
900    /**
901     * Set while we are wanting to sleep, to prevent any
902     * activities from being started/resumed.
903     */
904    private boolean mSleeping = false;
905
906    /**
907     * Set while we are running a voice interaction.  This overrides
908     * sleeping while it is active.
909     */
910    private boolean mRunningVoice = false;
911
912    /**
913     * State of external calls telling us if the device is asleep.
914     */
915    private boolean mWentToSleep = false;
916
917    /**
918     * State of external call telling us if the lock screen is shown.
919     */
920    private boolean mLockScreenShown = false;
921
922    /**
923     * Set if we are shutting down the system, similar to sleeping.
924     */
925    boolean mShuttingDown = false;
926
927    /**
928     * Current sequence id for oom_adj computation traversal.
929     */
930    int mAdjSeq = 0;
931
932    /**
933     * Current sequence id for process LRU updating.
934     */
935    int mLruSeq = 0;
936
937    /**
938     * Keep track of the non-cached/empty process we last found, to help
939     * determine how to distribute cached/empty processes next time.
940     */
941    int mNumNonCachedProcs = 0;
942
943    /**
944     * Keep track of the number of cached hidden procs, to balance oom adj
945     * distribution between those and empty procs.
946     */
947    int mNumCachedHiddenProcs = 0;
948
949    /**
950     * Keep track of the number of service processes we last found, to
951     * determine on the next iteration which should be B services.
952     */
953    int mNumServiceProcs = 0;
954    int mNewNumAServiceProcs = 0;
955    int mNewNumServiceProcs = 0;
956
957    /**
958     * Allow the current computed overall memory level of the system to go down?
959     * This is set to false when we are killing processes for reasons other than
960     * memory management, so that the now smaller process list will not be taken as
961     * an indication that memory is tighter.
962     */
963    boolean mAllowLowerMemLevel = false;
964
965    /**
966     * The last computed memory level, for holding when we are in a state that
967     * processes are going away for other reasons.
968     */
969    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
970
971    /**
972     * The last total number of process we have, to determine if changes actually look
973     * like a shrinking number of process due to lower RAM.
974     */
975    int mLastNumProcesses;
976
977    /**
978     * The uptime of the last time we performed idle maintenance.
979     */
980    long mLastIdleTime = SystemClock.uptimeMillis();
981
982    /**
983     * Total time spent with RAM that has been added in the past since the last idle time.
984     */
985    long mLowRamTimeSinceLastIdle = 0;
986
987    /**
988     * If RAM is currently low, when that horrible situation started.
989     */
990    long mLowRamStartTime = 0;
991
992    /**
993     * For reporting to battery stats the current top application.
994     */
995    private String mCurResumedPackage = null;
996    private int mCurResumedUid = -1;
997
998    /**
999     * For reporting to battery stats the apps currently running foreground
1000     * service.  The ProcessMap is package/uid tuples; each of these contain
1001     * an array of the currently foreground processes.
1002     */
1003    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1004            = new ProcessMap<ArrayList<ProcessRecord>>();
1005
1006    /**
1007     * This is set if we had to do a delayed dexopt of an app before launching
1008     * it, to increase the ANR timeouts in that case.
1009     */
1010    boolean mDidDexOpt;
1011
1012    /**
1013     * Set if the systemServer made a call to enterSafeMode.
1014     */
1015    boolean mSafeMode;
1016
1017    String mDebugApp = null;
1018    boolean mWaitForDebugger = false;
1019    boolean mDebugTransient = false;
1020    String mOrigDebugApp = null;
1021    boolean mOrigWaitForDebugger = false;
1022    boolean mAlwaysFinishActivities = false;
1023    IActivityController mController = null;
1024    String mProfileApp = null;
1025    ProcessRecord mProfileProc = null;
1026    String mProfileFile;
1027    ParcelFileDescriptor mProfileFd;
1028    int mProfileType = 0;
1029    boolean mAutoStopProfiler = false;
1030    String mOpenGlTraceApp = null;
1031
1032    static class ProcessChangeItem {
1033        static final int CHANGE_ACTIVITIES = 1<<0;
1034        static final int CHANGE_PROCESS_STATE = 1<<1;
1035        int changes;
1036        int uid;
1037        int pid;
1038        int processState;
1039        boolean foregroundActivities;
1040    }
1041
1042    final RemoteCallbackList<IProcessObserver> mProcessObservers
1043            = new RemoteCallbackList<IProcessObserver>();
1044    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1045
1046    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1047            = new ArrayList<ProcessChangeItem>();
1048    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1049            = new ArrayList<ProcessChangeItem>();
1050
1051    /**
1052     * Runtime CPU use collection thread.  This object's lock is used to
1053     * protect all related state.
1054     */
1055    final Thread mProcessCpuThread;
1056
1057    /**
1058     * Used to collect process stats when showing not responding dialog.
1059     * Protected by mProcessCpuThread.
1060     */
1061    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1062            MONITOR_THREAD_CPU_USAGE);
1063    final AtomicLong mLastCpuTime = new AtomicLong(0);
1064    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1065
1066    long mLastWriteTime = 0;
1067
1068    /**
1069     * Used to retain an update lock when the foreground activity is in
1070     * immersive mode.
1071     */
1072    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1073
1074    /**
1075     * Set to true after the system has finished booting.
1076     */
1077    boolean mBooted = false;
1078
1079    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1080    int mProcessLimitOverride = -1;
1081
1082    WindowManagerService mWindowManager;
1083
1084    final ActivityThread mSystemThread;
1085
1086    int mCurrentUserId = 0;
1087    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1088    private UserManagerService mUserManager;
1089
1090    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1091        final ProcessRecord mApp;
1092        final int mPid;
1093        final IApplicationThread mAppThread;
1094
1095        AppDeathRecipient(ProcessRecord app, int pid,
1096                IApplicationThread thread) {
1097            if (localLOGV) Slog.v(
1098                TAG, "New death recipient " + this
1099                + " for thread " + thread.asBinder());
1100            mApp = app;
1101            mPid = pid;
1102            mAppThread = thread;
1103        }
1104
1105        @Override
1106        public void binderDied() {
1107            if (localLOGV) Slog.v(
1108                TAG, "Death received in " + this
1109                + " for thread " + mAppThread.asBinder());
1110            synchronized(ActivityManagerService.this) {
1111                appDiedLocked(mApp, mPid, mAppThread);
1112            }
1113        }
1114    }
1115
1116    static final int SHOW_ERROR_MSG = 1;
1117    static final int SHOW_NOT_RESPONDING_MSG = 2;
1118    static final int SHOW_FACTORY_ERROR_MSG = 3;
1119    static final int UPDATE_CONFIGURATION_MSG = 4;
1120    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1121    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1122    static final int SERVICE_TIMEOUT_MSG = 12;
1123    static final int UPDATE_TIME_ZONE = 13;
1124    static final int SHOW_UID_ERROR_MSG = 14;
1125    static final int IM_FEELING_LUCKY_MSG = 15;
1126    static final int PROC_START_TIMEOUT_MSG = 20;
1127    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1128    static final int KILL_APPLICATION_MSG = 22;
1129    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1130    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1131    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1132    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1133    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1134    static final int CLEAR_DNS_CACHE_MSG = 28;
1135    static final int UPDATE_HTTP_PROXY_MSG = 29;
1136    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1137    static final int DISPATCH_PROCESSES_CHANGED = 31;
1138    static final int DISPATCH_PROCESS_DIED = 32;
1139    static final int REPORT_MEM_USAGE_MSG = 33;
1140    static final int REPORT_USER_SWITCH_MSG = 34;
1141    static final int CONTINUE_USER_SWITCH_MSG = 35;
1142    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1143    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1144    static final int PERSIST_URI_GRANTS_MSG = 38;
1145    static final int REQUEST_ALL_PSS_MSG = 39;
1146    static final int START_PROFILES_MSG = 40;
1147    static final int UPDATE_TIME = 41;
1148    static final int SYSTEM_USER_START_MSG = 42;
1149    static final int SYSTEM_USER_CURRENT_MSG = 43;
1150
1151    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1152    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1153    static final int FIRST_COMPAT_MODE_MSG = 300;
1154    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1155
1156    AlertDialog mUidAlert;
1157    CompatModeDialog mCompatModeDialog;
1158    long mLastMemUsageReportTime = 0;
1159
1160    /**
1161     * Flag whether the current user is a "monkey", i.e. whether
1162     * the UI is driven by a UI automation tool.
1163     */
1164    private boolean mUserIsMonkey;
1165
1166    final ServiceThread mHandlerThread;
1167    final MainHandler mHandler;
1168
1169    final class MainHandler extends Handler {
1170        public MainHandler(Looper looper) {
1171            super(looper, null, true);
1172        }
1173
1174        @Override
1175        public void handleMessage(Message msg) {
1176            switch (msg.what) {
1177            case SHOW_ERROR_MSG: {
1178                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1179                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1180                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1181                synchronized (ActivityManagerService.this) {
1182                    ProcessRecord proc = (ProcessRecord)data.get("app");
1183                    AppErrorResult res = (AppErrorResult) data.get("result");
1184                    if (proc != null && proc.crashDialog != null) {
1185                        Slog.e(TAG, "App already has crash dialog: " + proc);
1186                        if (res != null) {
1187                            res.set(0);
1188                        }
1189                        return;
1190                    }
1191                    if (!showBackground && UserHandle.getAppId(proc.uid)
1192                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1193                            && proc.pid != MY_PID) {
1194                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1195                        if (res != null) {
1196                            res.set(0);
1197                        }
1198                        return;
1199                    }
1200                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1201                        Dialog d = new AppErrorDialog(mContext,
1202                                ActivityManagerService.this, res, proc);
1203                        d.show();
1204                        proc.crashDialog = d;
1205                    } else {
1206                        // The device is asleep, so just pretend that the user
1207                        // saw a crash dialog and hit "force quit".
1208                        if (res != null) {
1209                            res.set(0);
1210                        }
1211                    }
1212                }
1213
1214                ensureBootCompleted();
1215            } break;
1216            case SHOW_NOT_RESPONDING_MSG: {
1217                synchronized (ActivityManagerService.this) {
1218                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1219                    ProcessRecord proc = (ProcessRecord)data.get("app");
1220                    if (proc != null && proc.anrDialog != null) {
1221                        Slog.e(TAG, "App already has anr dialog: " + proc);
1222                        return;
1223                    }
1224
1225                    Intent intent = new Intent("android.intent.action.ANR");
1226                    if (!mProcessesReady) {
1227                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1228                                | Intent.FLAG_RECEIVER_FOREGROUND);
1229                    }
1230                    broadcastIntentLocked(null, null, intent,
1231                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1232                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1233
1234                    if (mShowDialogs) {
1235                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1236                                mContext, proc, (ActivityRecord)data.get("activity"),
1237                                msg.arg1 != 0);
1238                        d.show();
1239                        proc.anrDialog = d;
1240                    } else {
1241                        // Just kill the app if there is no dialog to be shown.
1242                        killAppAtUsersRequest(proc, null);
1243                    }
1244                }
1245
1246                ensureBootCompleted();
1247            } break;
1248            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1249                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1250                synchronized (ActivityManagerService.this) {
1251                    ProcessRecord proc = (ProcessRecord) data.get("app");
1252                    if (proc == null) {
1253                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1254                        break;
1255                    }
1256                    if (proc.crashDialog != null) {
1257                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1258                        return;
1259                    }
1260                    AppErrorResult res = (AppErrorResult) data.get("result");
1261                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1262                        Dialog d = new StrictModeViolationDialog(mContext,
1263                                ActivityManagerService.this, res, proc);
1264                        d.show();
1265                        proc.crashDialog = d;
1266                    } else {
1267                        // The device is asleep, so just pretend that the user
1268                        // saw a crash dialog and hit "force quit".
1269                        res.set(0);
1270                    }
1271                }
1272                ensureBootCompleted();
1273            } break;
1274            case SHOW_FACTORY_ERROR_MSG: {
1275                Dialog d = new FactoryErrorDialog(
1276                    mContext, msg.getData().getCharSequence("msg"));
1277                d.show();
1278                ensureBootCompleted();
1279            } break;
1280            case UPDATE_CONFIGURATION_MSG: {
1281                final ContentResolver resolver = mContext.getContentResolver();
1282                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1283            } break;
1284            case GC_BACKGROUND_PROCESSES_MSG: {
1285                synchronized (ActivityManagerService.this) {
1286                    performAppGcsIfAppropriateLocked();
1287                }
1288            } break;
1289            case WAIT_FOR_DEBUGGER_MSG: {
1290                synchronized (ActivityManagerService.this) {
1291                    ProcessRecord app = (ProcessRecord)msg.obj;
1292                    if (msg.arg1 != 0) {
1293                        if (!app.waitedForDebugger) {
1294                            Dialog d = new AppWaitingForDebuggerDialog(
1295                                    ActivityManagerService.this,
1296                                    mContext, app);
1297                            app.waitDialog = d;
1298                            app.waitedForDebugger = true;
1299                            d.show();
1300                        }
1301                    } else {
1302                        if (app.waitDialog != null) {
1303                            app.waitDialog.dismiss();
1304                            app.waitDialog = null;
1305                        }
1306                    }
1307                }
1308            } break;
1309            case SERVICE_TIMEOUT_MSG: {
1310                if (mDidDexOpt) {
1311                    mDidDexOpt = false;
1312                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1313                    nmsg.obj = msg.obj;
1314                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1315                    return;
1316                }
1317                mServices.serviceTimeout((ProcessRecord)msg.obj);
1318            } break;
1319            case UPDATE_TIME_ZONE: {
1320                synchronized (ActivityManagerService.this) {
1321                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1322                        ProcessRecord r = mLruProcesses.get(i);
1323                        if (r.thread != null) {
1324                            try {
1325                                r.thread.updateTimeZone();
1326                            } catch (RemoteException ex) {
1327                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1328                            }
1329                        }
1330                    }
1331                }
1332            } break;
1333            case CLEAR_DNS_CACHE_MSG: {
1334                synchronized (ActivityManagerService.this) {
1335                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1336                        ProcessRecord r = mLruProcesses.get(i);
1337                        if (r.thread != null) {
1338                            try {
1339                                r.thread.clearDnsCache();
1340                            } catch (RemoteException ex) {
1341                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1342                            }
1343                        }
1344                    }
1345                }
1346            } break;
1347            case UPDATE_HTTP_PROXY_MSG: {
1348                ProxyInfo proxy = (ProxyInfo)msg.obj;
1349                String host = "";
1350                String port = "";
1351                String exclList = "";
1352                Uri pacFileUrl = Uri.EMPTY;
1353                if (proxy != null) {
1354                    host = proxy.getHost();
1355                    port = Integer.toString(proxy.getPort());
1356                    exclList = proxy.getExclusionListAsString();
1357                    pacFileUrl = proxy.getPacFileUrl();
1358                }
1359                synchronized (ActivityManagerService.this) {
1360                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1361                        ProcessRecord r = mLruProcesses.get(i);
1362                        if (r.thread != null) {
1363                            try {
1364                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1365                            } catch (RemoteException ex) {
1366                                Slog.w(TAG, "Failed to update http proxy for: " +
1367                                        r.info.processName);
1368                            }
1369                        }
1370                    }
1371                }
1372            } break;
1373            case SHOW_UID_ERROR_MSG: {
1374                String title = "System UIDs Inconsistent";
1375                String text = "UIDs on the system are inconsistent, you need to wipe your"
1376                        + " data partition or your device will be unstable.";
1377                Log.e(TAG, title + ": " + text);
1378                if (mShowDialogs) {
1379                    // XXX This is a temporary dialog, no need to localize.
1380                    AlertDialog d = new BaseErrorDialog(mContext);
1381                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1382                    d.setCancelable(false);
1383                    d.setTitle(title);
1384                    d.setMessage(text);
1385                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1386                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1387                    mUidAlert = d;
1388                    d.show();
1389                }
1390            } break;
1391            case IM_FEELING_LUCKY_MSG: {
1392                if (mUidAlert != null) {
1393                    mUidAlert.dismiss();
1394                    mUidAlert = null;
1395                }
1396            } break;
1397            case PROC_START_TIMEOUT_MSG: {
1398                if (mDidDexOpt) {
1399                    mDidDexOpt = false;
1400                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1401                    nmsg.obj = msg.obj;
1402                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1403                    return;
1404                }
1405                ProcessRecord app = (ProcessRecord)msg.obj;
1406                synchronized (ActivityManagerService.this) {
1407                    processStartTimedOutLocked(app);
1408                }
1409            } break;
1410            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1411                synchronized (ActivityManagerService.this) {
1412                    doPendingActivityLaunchesLocked(true);
1413                }
1414            } break;
1415            case KILL_APPLICATION_MSG: {
1416                synchronized (ActivityManagerService.this) {
1417                    int appid = msg.arg1;
1418                    boolean restart = (msg.arg2 == 1);
1419                    Bundle bundle = (Bundle)msg.obj;
1420                    String pkg = bundle.getString("pkg");
1421                    String reason = bundle.getString("reason");
1422                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1423                            false, UserHandle.USER_ALL, reason);
1424                }
1425            } break;
1426            case FINALIZE_PENDING_INTENT_MSG: {
1427                ((PendingIntentRecord)msg.obj).completeFinalize();
1428            } break;
1429            case POST_HEAVY_NOTIFICATION_MSG: {
1430                INotificationManager inm = NotificationManager.getService();
1431                if (inm == null) {
1432                    return;
1433                }
1434
1435                ActivityRecord root = (ActivityRecord)msg.obj;
1436                ProcessRecord process = root.app;
1437                if (process == null) {
1438                    return;
1439                }
1440
1441                try {
1442                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1443                    String text = mContext.getString(R.string.heavy_weight_notification,
1444                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1445                    Notification notification = new Notification();
1446                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1447                    notification.when = 0;
1448                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1449                    notification.tickerText = text;
1450                    notification.defaults = 0; // please be quiet
1451                    notification.sound = null;
1452                    notification.vibrate = null;
1453                    notification.setLatestEventInfo(context, text,
1454                            mContext.getText(R.string.heavy_weight_notification_detail),
1455                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1456                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1457                                    new UserHandle(root.userId)));
1458
1459                    try {
1460                        int[] outId = new int[1];
1461                        inm.enqueueNotificationWithTag("android", "android", null,
1462                                R.string.heavy_weight_notification,
1463                                notification, outId, root.userId);
1464                    } catch (RuntimeException e) {
1465                        Slog.w(ActivityManagerService.TAG,
1466                                "Error showing notification for heavy-weight app", e);
1467                    } catch (RemoteException e) {
1468                    }
1469                } catch (NameNotFoundException e) {
1470                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1471                }
1472            } break;
1473            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1474                INotificationManager inm = NotificationManager.getService();
1475                if (inm == null) {
1476                    return;
1477                }
1478                try {
1479                    inm.cancelNotificationWithTag("android", null,
1480                            R.string.heavy_weight_notification,  msg.arg1);
1481                } catch (RuntimeException e) {
1482                    Slog.w(ActivityManagerService.TAG,
1483                            "Error canceling notification for service", e);
1484                } catch (RemoteException e) {
1485                }
1486            } break;
1487            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1488                synchronized (ActivityManagerService.this) {
1489                    checkExcessivePowerUsageLocked(true);
1490                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1491                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1492                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1493                }
1494            } break;
1495            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1496                synchronized (ActivityManagerService.this) {
1497                    ActivityRecord ar = (ActivityRecord)msg.obj;
1498                    if (mCompatModeDialog != null) {
1499                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1500                                ar.info.applicationInfo.packageName)) {
1501                            return;
1502                        }
1503                        mCompatModeDialog.dismiss();
1504                        mCompatModeDialog = null;
1505                    }
1506                    if (ar != null && false) {
1507                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1508                                ar.packageName)) {
1509                            int mode = mCompatModePackages.computeCompatModeLocked(
1510                                    ar.info.applicationInfo);
1511                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1512                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1513                                mCompatModeDialog = new CompatModeDialog(
1514                                        ActivityManagerService.this, mContext,
1515                                        ar.info.applicationInfo);
1516                                mCompatModeDialog.show();
1517                            }
1518                        }
1519                    }
1520                }
1521                break;
1522            }
1523            case DISPATCH_PROCESSES_CHANGED: {
1524                dispatchProcessesChanged();
1525                break;
1526            }
1527            case DISPATCH_PROCESS_DIED: {
1528                final int pid = msg.arg1;
1529                final int uid = msg.arg2;
1530                dispatchProcessDied(pid, uid);
1531                break;
1532            }
1533            case REPORT_MEM_USAGE_MSG: {
1534                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1535                Thread thread = new Thread() {
1536                    @Override public void run() {
1537                        final SparseArray<ProcessMemInfo> infoMap
1538                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1539                        for (int i=0, N=memInfos.size(); i<N; i++) {
1540                            ProcessMemInfo mi = memInfos.get(i);
1541                            infoMap.put(mi.pid, mi);
1542                        }
1543                        updateCpuStatsNow();
1544                        synchronized (mProcessCpuThread) {
1545                            final int N = mProcessCpuTracker.countStats();
1546                            for (int i=0; i<N; i++) {
1547                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1548                                if (st.vsize > 0) {
1549                                    long pss = Debug.getPss(st.pid, null);
1550                                    if (pss > 0) {
1551                                        if (infoMap.indexOfKey(st.pid) < 0) {
1552                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1553                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1554                                            mi.pss = pss;
1555                                            memInfos.add(mi);
1556                                        }
1557                                    }
1558                                }
1559                            }
1560                        }
1561
1562                        long totalPss = 0;
1563                        for (int i=0, N=memInfos.size(); i<N; i++) {
1564                            ProcessMemInfo mi = memInfos.get(i);
1565                            if (mi.pss == 0) {
1566                                mi.pss = Debug.getPss(mi.pid, null);
1567                            }
1568                            totalPss += mi.pss;
1569                        }
1570                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1571                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1572                                if (lhs.oomAdj != rhs.oomAdj) {
1573                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1574                                }
1575                                if (lhs.pss != rhs.pss) {
1576                                    return lhs.pss < rhs.pss ? 1 : -1;
1577                                }
1578                                return 0;
1579                            }
1580                        });
1581
1582                        StringBuilder tag = new StringBuilder(128);
1583                        StringBuilder stack = new StringBuilder(128);
1584                        tag.append("Low on memory -- ");
1585                        appendMemBucket(tag, totalPss, "total", false);
1586                        appendMemBucket(stack, totalPss, "total", true);
1587
1588                        StringBuilder logBuilder = new StringBuilder(1024);
1589                        logBuilder.append("Low on memory:\n");
1590
1591                        boolean firstLine = true;
1592                        int lastOomAdj = Integer.MIN_VALUE;
1593                        for (int i=0, N=memInfos.size(); i<N; i++) {
1594                            ProcessMemInfo mi = memInfos.get(i);
1595
1596                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1597                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1598                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1599                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1600                                if (lastOomAdj != mi.oomAdj) {
1601                                    lastOomAdj = mi.oomAdj;
1602                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1603                                        tag.append(" / ");
1604                                    }
1605                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1606                                        if (firstLine) {
1607                                            stack.append(":");
1608                                            firstLine = false;
1609                                        }
1610                                        stack.append("\n\t at ");
1611                                    } else {
1612                                        stack.append("$");
1613                                    }
1614                                } else {
1615                                    tag.append(" ");
1616                                    stack.append("$");
1617                                }
1618                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1619                                    appendMemBucket(tag, mi.pss, mi.name, false);
1620                                }
1621                                appendMemBucket(stack, mi.pss, mi.name, true);
1622                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1623                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1624                                    stack.append("(");
1625                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1626                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1627                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1628                                            stack.append(":");
1629                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1630                                        }
1631                                    }
1632                                    stack.append(")");
1633                                }
1634                            }
1635
1636                            logBuilder.append("  ");
1637                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1638                            logBuilder.append(' ');
1639                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1640                            logBuilder.append(' ');
1641                            ProcessList.appendRamKb(logBuilder, mi.pss);
1642                            logBuilder.append(" kB: ");
1643                            logBuilder.append(mi.name);
1644                            logBuilder.append(" (");
1645                            logBuilder.append(mi.pid);
1646                            logBuilder.append(") ");
1647                            logBuilder.append(mi.adjType);
1648                            logBuilder.append('\n');
1649                            if (mi.adjReason != null) {
1650                                logBuilder.append("                      ");
1651                                logBuilder.append(mi.adjReason);
1652                                logBuilder.append('\n');
1653                            }
1654                        }
1655
1656                        logBuilder.append("           ");
1657                        ProcessList.appendRamKb(logBuilder, totalPss);
1658                        logBuilder.append(" kB: TOTAL\n");
1659
1660                        long[] infos = new long[Debug.MEMINFO_COUNT];
1661                        Debug.getMemInfo(infos);
1662                        logBuilder.append("  MemInfo: ");
1663                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1664                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1665                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1666                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1667                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1668                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1669                            logBuilder.append("  ZRAM: ");
1670                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1671                            logBuilder.append(" kB RAM, ");
1672                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1673                            logBuilder.append(" kB swap total, ");
1674                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1675                            logBuilder.append(" kB swap free\n");
1676                        }
1677                        Slog.i(TAG, logBuilder.toString());
1678
1679                        StringBuilder dropBuilder = new StringBuilder(1024);
1680                        /*
1681                        StringWriter oomSw = new StringWriter();
1682                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1683                        StringWriter catSw = new StringWriter();
1684                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1685                        String[] emptyArgs = new String[] { };
1686                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1687                        oomPw.flush();
1688                        String oomString = oomSw.toString();
1689                        */
1690                        dropBuilder.append(stack);
1691                        dropBuilder.append('\n');
1692                        dropBuilder.append('\n');
1693                        dropBuilder.append(logBuilder);
1694                        dropBuilder.append('\n');
1695                        /*
1696                        dropBuilder.append(oomString);
1697                        dropBuilder.append('\n');
1698                        */
1699                        StringWriter catSw = new StringWriter();
1700                        synchronized (ActivityManagerService.this) {
1701                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1702                            String[] emptyArgs = new String[] { };
1703                            catPw.println();
1704                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1705                            catPw.println();
1706                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1707                                    false, false, null);
1708                            catPw.println();
1709                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1710                            catPw.flush();
1711                        }
1712                        dropBuilder.append(catSw.toString());
1713                        addErrorToDropBox("lowmem", null, "system_server", null,
1714                                null, tag.toString(), dropBuilder.toString(), null, null);
1715                        //Slog.i(TAG, "Sent to dropbox:");
1716                        //Slog.i(TAG, dropBuilder.toString());
1717                        synchronized (ActivityManagerService.this) {
1718                            long now = SystemClock.uptimeMillis();
1719                            if (mLastMemUsageReportTime < now) {
1720                                mLastMemUsageReportTime = now;
1721                            }
1722                        }
1723                    }
1724                };
1725                thread.start();
1726                break;
1727            }
1728            case REPORT_USER_SWITCH_MSG: {
1729                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1730                break;
1731            }
1732            case CONTINUE_USER_SWITCH_MSG: {
1733                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1734                break;
1735            }
1736            case USER_SWITCH_TIMEOUT_MSG: {
1737                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1738                break;
1739            }
1740            case IMMERSIVE_MODE_LOCK_MSG: {
1741                final boolean nextState = (msg.arg1 != 0);
1742                if (mUpdateLock.isHeld() != nextState) {
1743                    if (DEBUG_IMMERSIVE) {
1744                        final ActivityRecord r = (ActivityRecord) msg.obj;
1745                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1746                    }
1747                    if (nextState) {
1748                        mUpdateLock.acquire();
1749                    } else {
1750                        mUpdateLock.release();
1751                    }
1752                }
1753                break;
1754            }
1755            case PERSIST_URI_GRANTS_MSG: {
1756                writeGrantedUriPermissions();
1757                break;
1758            }
1759            case REQUEST_ALL_PSS_MSG: {
1760                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1761                break;
1762            }
1763            case START_PROFILES_MSG: {
1764                synchronized (ActivityManagerService.this) {
1765                    startProfilesLocked();
1766                }
1767                break;
1768            }
1769            case UPDATE_TIME: {
1770                synchronized (ActivityManagerService.this) {
1771                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1772                        ProcessRecord r = mLruProcesses.get(i);
1773                        if (r.thread != null) {
1774                            try {
1775                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1776                            } catch (RemoteException ex) {
1777                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1778                            }
1779                        }
1780                    }
1781                }
1782                break;
1783            }
1784            case SYSTEM_USER_START_MSG: {
1785                mSystemServiceManager.startUser(msg.arg1);
1786                break;
1787            }
1788            case SYSTEM_USER_CURRENT_MSG: {
1789                mSystemServiceManager.switchUser(msg.arg1);
1790                break;
1791            }
1792            }
1793        }
1794    };
1795
1796    static final int COLLECT_PSS_BG_MSG = 1;
1797
1798    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1799        @Override
1800        public void handleMessage(Message msg) {
1801            switch (msg.what) {
1802            case COLLECT_PSS_BG_MSG: {
1803                int i=0, num=0;
1804                long start = SystemClock.uptimeMillis();
1805                long[] tmp = new long[1];
1806                do {
1807                    ProcessRecord proc;
1808                    int procState;
1809                    int pid;
1810                    synchronized (ActivityManagerService.this) {
1811                        if (i >= mPendingPssProcesses.size()) {
1812                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1813                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1814                            mPendingPssProcesses.clear();
1815                            return;
1816                        }
1817                        proc = mPendingPssProcesses.get(i);
1818                        procState = proc.pssProcState;
1819                        if (proc.thread != null && procState == proc.setProcState) {
1820                            pid = proc.pid;
1821                        } else {
1822                            proc = null;
1823                            pid = 0;
1824                        }
1825                        i++;
1826                    }
1827                    if (proc != null) {
1828                        long pss = Debug.getPss(pid, tmp);
1829                        synchronized (ActivityManagerService.this) {
1830                            if (proc.thread != null && proc.setProcState == procState
1831                                    && proc.pid == pid) {
1832                                num++;
1833                                proc.lastPssTime = SystemClock.uptimeMillis();
1834                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1835                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1836                                        + ": " + pss + " lastPss=" + proc.lastPss
1837                                        + " state=" + ProcessList.makeProcStateString(procState));
1838                                if (proc.initialIdlePss == 0) {
1839                                    proc.initialIdlePss = pss;
1840                                }
1841                                proc.lastPss = pss;
1842                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1843                                    proc.lastCachedPss = pss;
1844                                }
1845                            }
1846                        }
1847                    }
1848                } while (true);
1849            }
1850            }
1851        }
1852    };
1853
1854    /**
1855     * Monitor for package changes and update our internal state.
1856     */
1857    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1858        @Override
1859        public void onPackageRemoved(String packageName, int uid) {
1860            // Remove all tasks with activities in the specified package from the list of recent tasks
1861            synchronized (ActivityManagerService.this) {
1862                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1863                    TaskRecord tr = mRecentTasks.get(i);
1864                    ComponentName cn = tr.intent.getComponent();
1865                    if (cn != null && cn.getPackageName().equals(packageName)) {
1866                        // If the package name matches, remove the task and kill the process
1867                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1868                    }
1869                }
1870            }
1871        }
1872
1873        @Override
1874        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1875            onPackageModified(packageName);
1876            return true;
1877        }
1878
1879        @Override
1880        public void onPackageModified(String packageName) {
1881            final PackageManager pm = mContext.getPackageManager();
1882            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1883                    new ArrayList<Pair<Intent, Integer>>();
1884            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1885            // Copy the list of recent tasks so that we don't hold onto the lock on
1886            // ActivityManagerService for long periods while checking if components exist.
1887            synchronized (ActivityManagerService.this) {
1888                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1889                    TaskRecord tr = mRecentTasks.get(i);
1890                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1891                }
1892            }
1893            // Check the recent tasks and filter out all tasks with components that no longer exist.
1894            Intent tmpI = new Intent();
1895            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1896                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1897                ComponentName cn = p.first.getComponent();
1898                if (cn != null && cn.getPackageName().equals(packageName)) {
1899                    try {
1900                        // Add the task to the list to remove if the component no longer exists
1901                        tmpI.setComponent(cn);
1902                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1903                            tasksToRemove.add(p.second);
1904                        }
1905                    } catch (Exception e) {}
1906                }
1907            }
1908            // Prune all the tasks with removed components from the list of recent tasks
1909            synchronized (ActivityManagerService.this) {
1910                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1911                    // Remove the task but don't kill the process (since other components in that
1912                    // package may still be running and in the background)
1913                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1914                }
1915            }
1916        }
1917
1918        @Override
1919        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1920            // Force stop the specified packages
1921            if (packages != null) {
1922                for (String pkg : packages) {
1923                    synchronized (ActivityManagerService.this) {
1924                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1925                                "finished booting")) {
1926                            return true;
1927                        }
1928                    }
1929                }
1930            }
1931            return false;
1932        }
1933    };
1934
1935    public void setSystemProcess() {
1936        try {
1937            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1938            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1939            ServiceManager.addService("meminfo", new MemBinder(this));
1940            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1941            ServiceManager.addService("dbinfo", new DbBinder(this));
1942            if (MONITOR_CPU_USAGE) {
1943                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1944            }
1945            ServiceManager.addService("permission", new PermissionController(this));
1946
1947            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1948                    "android", STOCK_PM_FLAGS);
1949            mSystemThread.installSystemApplicationInfo(info);
1950
1951            synchronized (this) {
1952                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1953                app.persistent = true;
1954                app.pid = MY_PID;
1955                app.maxAdj = ProcessList.SYSTEM_ADJ;
1956                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1957                mProcessNames.put(app.processName, app.uid, app);
1958                synchronized (mPidsSelfLocked) {
1959                    mPidsSelfLocked.put(app.pid, app);
1960                }
1961                updateLruProcessLocked(app, false, null);
1962                updateOomAdjLocked();
1963            }
1964        } catch (PackageManager.NameNotFoundException e) {
1965            throw new RuntimeException(
1966                    "Unable to find android system package", e);
1967        }
1968    }
1969
1970    public void setWindowManager(WindowManagerService wm) {
1971        mWindowManager = wm;
1972        mStackSupervisor.setWindowManager(wm);
1973    }
1974
1975    public void startObservingNativeCrashes() {
1976        final NativeCrashListener ncl = new NativeCrashListener(this);
1977        ncl.start();
1978    }
1979
1980    public IAppOpsService getAppOpsService() {
1981        return mAppOpsService;
1982    }
1983
1984    static class MemBinder extends Binder {
1985        ActivityManagerService mActivityManagerService;
1986        MemBinder(ActivityManagerService activityManagerService) {
1987            mActivityManagerService = activityManagerService;
1988        }
1989
1990        @Override
1991        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1992            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1993                    != PackageManager.PERMISSION_GRANTED) {
1994                pw.println("Permission Denial: can't dump meminfo from from pid="
1995                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1996                        + " without permission " + android.Manifest.permission.DUMP);
1997                return;
1998            }
1999
2000            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2001        }
2002    }
2003
2004    static class GraphicsBinder extends Binder {
2005        ActivityManagerService mActivityManagerService;
2006        GraphicsBinder(ActivityManagerService activityManagerService) {
2007            mActivityManagerService = activityManagerService;
2008        }
2009
2010        @Override
2011        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2012            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2013                    != PackageManager.PERMISSION_GRANTED) {
2014                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2015                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2016                        + " without permission " + android.Manifest.permission.DUMP);
2017                return;
2018            }
2019
2020            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2021        }
2022    }
2023
2024    static class DbBinder extends Binder {
2025        ActivityManagerService mActivityManagerService;
2026        DbBinder(ActivityManagerService activityManagerService) {
2027            mActivityManagerService = activityManagerService;
2028        }
2029
2030        @Override
2031        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2032            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2033                    != PackageManager.PERMISSION_GRANTED) {
2034                pw.println("Permission Denial: can't dump dbinfo from from pid="
2035                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2036                        + " without permission " + android.Manifest.permission.DUMP);
2037                return;
2038            }
2039
2040            mActivityManagerService.dumpDbInfo(fd, pw, args);
2041        }
2042    }
2043
2044    static class CpuBinder extends Binder {
2045        ActivityManagerService mActivityManagerService;
2046        CpuBinder(ActivityManagerService activityManagerService) {
2047            mActivityManagerService = activityManagerService;
2048        }
2049
2050        @Override
2051        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2052            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2053                    != PackageManager.PERMISSION_GRANTED) {
2054                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2055                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2056                        + " without permission " + android.Manifest.permission.DUMP);
2057                return;
2058            }
2059
2060            synchronized (mActivityManagerService.mProcessCpuThread) {
2061                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2062                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2063                        SystemClock.uptimeMillis()));
2064            }
2065        }
2066    }
2067
2068    public static final class Lifecycle extends SystemService {
2069        private final ActivityManagerService mService;
2070
2071        public Lifecycle(Context context) {
2072            super(context);
2073            mService = new ActivityManagerService(context);
2074        }
2075
2076        @Override
2077        public void onStart() {
2078            mService.start();
2079        }
2080
2081        public ActivityManagerService getService() {
2082            return mService;
2083        }
2084    }
2085
2086    // Note: This method is invoked on the main thread but may need to attach various
2087    // handlers to other threads.  So take care to be explicit about the looper.
2088    public ActivityManagerService(Context systemContext) {
2089        mContext = systemContext;
2090        mFactoryTest = FactoryTest.getMode();
2091        mSystemThread = ActivityThread.currentActivityThread();
2092
2093        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2094
2095        mHandlerThread = new ServiceThread(TAG,
2096                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2097        mHandlerThread.start();
2098        mHandler = new MainHandler(mHandlerThread.getLooper());
2099
2100        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2101                "foreground", BROADCAST_FG_TIMEOUT, false);
2102        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2103                "background", BROADCAST_BG_TIMEOUT, true);
2104        mBroadcastQueues[0] = mFgBroadcastQueue;
2105        mBroadcastQueues[1] = mBgBroadcastQueue;
2106
2107        mServices = new ActiveServices(this);
2108        mProviderMap = new ProviderMap(this);
2109
2110        // TODO: Move creation of battery stats service outside of activity manager service.
2111        File dataDir = Environment.getDataDirectory();
2112        File systemDir = new File(dataDir, "system");
2113        systemDir.mkdirs();
2114        mBatteryStatsService = new BatteryStatsService(new File(
2115                systemDir, "batterystats.bin").toString(), mHandler);
2116        mBatteryStatsService.getActiveStatistics().readLocked();
2117        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2118        mOnBattery = DEBUG_POWER ? true
2119                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2120        mBatteryStatsService.getActiveStatistics().setCallback(this);
2121
2122        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2123
2124        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2125        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2126
2127        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2128
2129        // User 0 is the first and only user that runs at boot.
2130        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2131        mUserLru.add(Integer.valueOf(0));
2132        updateStartedUserArrayLocked();
2133
2134        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2135            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2136
2137        mConfiguration.setToDefaults();
2138        mConfiguration.setLocale(Locale.getDefault());
2139
2140        mConfigurationSeq = mConfiguration.seq = 1;
2141        mProcessCpuTracker.init();
2142
2143        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2144        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2145        mStackSupervisor = new ActivityStackSupervisor(this);
2146        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2147
2148        mProcessCpuThread = new Thread("CpuTracker") {
2149            @Override
2150            public void run() {
2151                while (true) {
2152                    try {
2153                        try {
2154                            synchronized(this) {
2155                                final long now = SystemClock.uptimeMillis();
2156                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2157                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2158                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2159                                //        + ", write delay=" + nextWriteDelay);
2160                                if (nextWriteDelay < nextCpuDelay) {
2161                                    nextCpuDelay = nextWriteDelay;
2162                                }
2163                                if (nextCpuDelay > 0) {
2164                                    mProcessCpuMutexFree.set(true);
2165                                    this.wait(nextCpuDelay);
2166                                }
2167                            }
2168                        } catch (InterruptedException e) {
2169                        }
2170                        updateCpuStatsNow();
2171                    } catch (Exception e) {
2172                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2173                    }
2174                }
2175            }
2176        };
2177
2178        Watchdog.getInstance().addMonitor(this);
2179        Watchdog.getInstance().addThread(mHandler);
2180    }
2181
2182    public void setSystemServiceManager(SystemServiceManager mgr) {
2183        mSystemServiceManager = mgr;
2184    }
2185
2186    private void start() {
2187        mProcessCpuThread.start();
2188
2189        mBatteryStatsService.publish(mContext);
2190        mUsageStatsService.publish(mContext);
2191        mAppOpsService.publish(mContext);
2192
2193        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2194    }
2195
2196    @Override
2197    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2198            throws RemoteException {
2199        if (code == SYSPROPS_TRANSACTION) {
2200            // We need to tell all apps about the system property change.
2201            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2202            synchronized(this) {
2203                final int NP = mProcessNames.getMap().size();
2204                for (int ip=0; ip<NP; ip++) {
2205                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2206                    final int NA = apps.size();
2207                    for (int ia=0; ia<NA; ia++) {
2208                        ProcessRecord app = apps.valueAt(ia);
2209                        if (app.thread != null) {
2210                            procs.add(app.thread.asBinder());
2211                        }
2212                    }
2213                }
2214            }
2215
2216            int N = procs.size();
2217            for (int i=0; i<N; i++) {
2218                Parcel data2 = Parcel.obtain();
2219                try {
2220                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2221                } catch (RemoteException e) {
2222                }
2223                data2.recycle();
2224            }
2225        }
2226        try {
2227            return super.onTransact(code, data, reply, flags);
2228        } catch (RuntimeException e) {
2229            // The activity manager only throws security exceptions, so let's
2230            // log all others.
2231            if (!(e instanceof SecurityException)) {
2232                Slog.wtf(TAG, "Activity Manager Crash", e);
2233            }
2234            throw e;
2235        }
2236    }
2237
2238    void updateCpuStats() {
2239        final long now = SystemClock.uptimeMillis();
2240        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2241            return;
2242        }
2243        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2244            synchronized (mProcessCpuThread) {
2245                mProcessCpuThread.notify();
2246            }
2247        }
2248    }
2249
2250    void updateCpuStatsNow() {
2251        synchronized (mProcessCpuThread) {
2252            mProcessCpuMutexFree.set(false);
2253            final long now = SystemClock.uptimeMillis();
2254            boolean haveNewCpuStats = false;
2255
2256            if (MONITOR_CPU_USAGE &&
2257                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2258                mLastCpuTime.set(now);
2259                haveNewCpuStats = true;
2260                mProcessCpuTracker.update();
2261                //Slog.i(TAG, mProcessCpu.printCurrentState());
2262                //Slog.i(TAG, "Total CPU usage: "
2263                //        + mProcessCpu.getTotalCpuPercent() + "%");
2264
2265                // Slog the cpu usage if the property is set.
2266                if ("true".equals(SystemProperties.get("events.cpu"))) {
2267                    int user = mProcessCpuTracker.getLastUserTime();
2268                    int system = mProcessCpuTracker.getLastSystemTime();
2269                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2270                    int irq = mProcessCpuTracker.getLastIrqTime();
2271                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2272                    int idle = mProcessCpuTracker.getLastIdleTime();
2273
2274                    int total = user + system + iowait + irq + softIrq + idle;
2275                    if (total == 0) total = 1;
2276
2277                    EventLog.writeEvent(EventLogTags.CPU,
2278                            ((user+system+iowait+irq+softIrq) * 100) / total,
2279                            (user * 100) / total,
2280                            (system * 100) / total,
2281                            (iowait * 100) / total,
2282                            (irq * 100) / total,
2283                            (softIrq * 100) / total);
2284                }
2285            }
2286
2287            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2288            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2289            synchronized(bstats) {
2290                synchronized(mPidsSelfLocked) {
2291                    if (haveNewCpuStats) {
2292                        if (mOnBattery) {
2293                            int perc = bstats.startAddingCpuLocked();
2294                            int totalUTime = 0;
2295                            int totalSTime = 0;
2296                            final int N = mProcessCpuTracker.countStats();
2297                            for (int i=0; i<N; i++) {
2298                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2299                                if (!st.working) {
2300                                    continue;
2301                                }
2302                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2303                                int otherUTime = (st.rel_utime*perc)/100;
2304                                int otherSTime = (st.rel_stime*perc)/100;
2305                                totalUTime += otherUTime;
2306                                totalSTime += otherSTime;
2307                                if (pr != null) {
2308                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2309                                    if (ps == null || !ps.isActive()) {
2310                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2311                                                pr.info.uid, pr.processName);
2312                                    }
2313                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2314                                            st.rel_stime-otherSTime);
2315                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2316                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2317                                } else {
2318                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2319                                    if (ps == null || !ps.isActive()) {
2320                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2321                                                bstats.mapUid(st.uid), st.name);
2322                                    }
2323                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2324                                            st.rel_stime-otherSTime);
2325                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2326                                }
2327                            }
2328                            bstats.finishAddingCpuLocked(perc, totalUTime,
2329                                    totalSTime, cpuSpeedTimes);
2330                        }
2331                    }
2332                }
2333
2334                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2335                    mLastWriteTime = now;
2336                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2337                }
2338            }
2339        }
2340    }
2341
2342    @Override
2343    public void batteryNeedsCpuUpdate() {
2344        updateCpuStatsNow();
2345    }
2346
2347    @Override
2348    public void batteryPowerChanged(boolean onBattery) {
2349        // When plugging in, update the CPU stats first before changing
2350        // the plug state.
2351        updateCpuStatsNow();
2352        synchronized (this) {
2353            synchronized(mPidsSelfLocked) {
2354                mOnBattery = DEBUG_POWER ? true : onBattery;
2355            }
2356        }
2357    }
2358
2359    /**
2360     * Initialize the application bind args. These are passed to each
2361     * process when the bindApplication() IPC is sent to the process. They're
2362     * lazily setup to make sure the services are running when they're asked for.
2363     */
2364    private HashMap<String, IBinder> getCommonServicesLocked() {
2365        if (mAppBindArgs == null) {
2366            mAppBindArgs = new HashMap<String, IBinder>();
2367
2368            // Setup the application init args
2369            mAppBindArgs.put("package", ServiceManager.getService("package"));
2370            mAppBindArgs.put("window", ServiceManager.getService("window"));
2371            mAppBindArgs.put(Context.ALARM_SERVICE,
2372                    ServiceManager.getService(Context.ALARM_SERVICE));
2373        }
2374        return mAppBindArgs;
2375    }
2376
2377    final void setFocusedActivityLocked(ActivityRecord r) {
2378        if (mFocusedActivity != r) {
2379            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2380            mFocusedActivity = r;
2381            if (r.task != null && r.task.voiceInteractor != null) {
2382                startRunningVoiceLocked();
2383            } else {
2384                finishRunningVoiceLocked();
2385            }
2386            mStackSupervisor.setFocusedStack(r);
2387            if (r != null) {
2388                mWindowManager.setFocusedApp(r.appToken, true);
2389            }
2390            applyUpdateLockStateLocked(r);
2391        }
2392    }
2393
2394    final void clearFocusedActivity(ActivityRecord r) {
2395        if (mFocusedActivity == r) {
2396            mFocusedActivity = null;
2397        }
2398    }
2399
2400    @Override
2401    public void setFocusedStack(int stackId) {
2402        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2403        synchronized (ActivityManagerService.this) {
2404            ActivityStack stack = mStackSupervisor.getStack(stackId);
2405            if (stack != null) {
2406                ActivityRecord r = stack.topRunningActivityLocked(null);
2407                if (r != null) {
2408                    setFocusedActivityLocked(r);
2409                }
2410            }
2411        }
2412    }
2413
2414    @Override
2415    public void notifyActivityDrawn(IBinder token) {
2416        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2417        synchronized (this) {
2418            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2419            if (r != null) {
2420                r.task.stack.notifyActivityDrawnLocked(r);
2421            }
2422        }
2423    }
2424
2425    final void applyUpdateLockStateLocked(ActivityRecord r) {
2426        // Modifications to the UpdateLock state are done on our handler, outside
2427        // the activity manager's locks.  The new state is determined based on the
2428        // state *now* of the relevant activity record.  The object is passed to
2429        // the handler solely for logging detail, not to be consulted/modified.
2430        final boolean nextState = r != null && r.immersive;
2431        mHandler.sendMessage(
2432                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2433    }
2434
2435    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2436        Message msg = Message.obtain();
2437        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2438        msg.obj = r.task.askedCompatMode ? null : r;
2439        mHandler.sendMessage(msg);
2440    }
2441
2442    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2443            String what, Object obj, ProcessRecord srcApp) {
2444        app.lastActivityTime = now;
2445
2446        if (app.activities.size() > 0) {
2447            // Don't want to touch dependent processes that are hosting activities.
2448            return index;
2449        }
2450
2451        int lrui = mLruProcesses.lastIndexOf(app);
2452        if (lrui < 0) {
2453            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2454                    + what + " " + obj + " from " + srcApp);
2455            return index;
2456        }
2457
2458        if (lrui >= index) {
2459            // Don't want to cause this to move dependent processes *back* in the
2460            // list as if they were less frequently used.
2461            return index;
2462        }
2463
2464        if (lrui >= mLruProcessActivityStart) {
2465            // Don't want to touch dependent processes that are hosting activities.
2466            return index;
2467        }
2468
2469        mLruProcesses.remove(lrui);
2470        if (index > 0) {
2471            index--;
2472        }
2473        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2474                + " in LRU list: " + app);
2475        mLruProcesses.add(index, app);
2476        return index;
2477    }
2478
2479    final void removeLruProcessLocked(ProcessRecord app) {
2480        int lrui = mLruProcesses.lastIndexOf(app);
2481        if (lrui >= 0) {
2482            if (lrui <= mLruProcessActivityStart) {
2483                mLruProcessActivityStart--;
2484            }
2485            if (lrui <= mLruProcessServiceStart) {
2486                mLruProcessServiceStart--;
2487            }
2488            mLruProcesses.remove(lrui);
2489        }
2490    }
2491
2492    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2493            ProcessRecord client) {
2494        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2495                || app.treatLikeActivity;
2496        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2497        if (!activityChange && hasActivity) {
2498            // The process has activities, so we are only allowing activity-based adjustments
2499            // to move it.  It should be kept in the front of the list with other
2500            // processes that have activities, and we don't want those to change their
2501            // order except due to activity operations.
2502            return;
2503        }
2504
2505        mLruSeq++;
2506        final long now = SystemClock.uptimeMillis();
2507        app.lastActivityTime = now;
2508
2509        // First a quick reject: if the app is already at the position we will
2510        // put it, then there is nothing to do.
2511        if (hasActivity) {
2512            final int N = mLruProcesses.size();
2513            if (N > 0 && mLruProcesses.get(N-1) == app) {
2514                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2515                return;
2516            }
2517        } else {
2518            if (mLruProcessServiceStart > 0
2519                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2520                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2521                return;
2522            }
2523        }
2524
2525        int lrui = mLruProcesses.lastIndexOf(app);
2526
2527        if (app.persistent && lrui >= 0) {
2528            // We don't care about the position of persistent processes, as long as
2529            // they are in the list.
2530            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2531            return;
2532        }
2533
2534        /* In progress: compute new position first, so we can avoid doing work
2535           if the process is not actually going to move.  Not yet working.
2536        int addIndex;
2537        int nextIndex;
2538        boolean inActivity = false, inService = false;
2539        if (hasActivity) {
2540            // Process has activities, put it at the very tipsy-top.
2541            addIndex = mLruProcesses.size();
2542            nextIndex = mLruProcessServiceStart;
2543            inActivity = true;
2544        } else if (hasService) {
2545            // Process has services, put it at the top of the service list.
2546            addIndex = mLruProcessActivityStart;
2547            nextIndex = mLruProcessServiceStart;
2548            inActivity = true;
2549            inService = true;
2550        } else  {
2551            // Process not otherwise of interest, it goes to the top of the non-service area.
2552            addIndex = mLruProcessServiceStart;
2553            if (client != null) {
2554                int clientIndex = mLruProcesses.lastIndexOf(client);
2555                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2556                        + app);
2557                if (clientIndex >= 0 && addIndex > clientIndex) {
2558                    addIndex = clientIndex;
2559                }
2560            }
2561            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2562        }
2563
2564        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2565                + mLruProcessActivityStart + "): " + app);
2566        */
2567
2568        if (lrui >= 0) {
2569            if (lrui < mLruProcessActivityStart) {
2570                mLruProcessActivityStart--;
2571            }
2572            if (lrui < mLruProcessServiceStart) {
2573                mLruProcessServiceStart--;
2574            }
2575            /*
2576            if (addIndex > lrui) {
2577                addIndex--;
2578            }
2579            if (nextIndex > lrui) {
2580                nextIndex--;
2581            }
2582            */
2583            mLruProcesses.remove(lrui);
2584        }
2585
2586        /*
2587        mLruProcesses.add(addIndex, app);
2588        if (inActivity) {
2589            mLruProcessActivityStart++;
2590        }
2591        if (inService) {
2592            mLruProcessActivityStart++;
2593        }
2594        */
2595
2596        int nextIndex;
2597        if (hasActivity) {
2598            final int N = mLruProcesses.size();
2599            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2600                // Process doesn't have activities, but has clients with
2601                // activities...  move it up, but one below the top (the top
2602                // should always have a real activity).
2603                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2604                mLruProcesses.add(N-1, app);
2605                // To keep it from spamming the LRU list (by making a bunch of clients),
2606                // we will push down any other entries owned by the app.
2607                final int uid = app.info.uid;
2608                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2609                    ProcessRecord subProc = mLruProcesses.get(i);
2610                    if (subProc.info.uid == uid) {
2611                        // We want to push this one down the list.  If the process after
2612                        // it is for the same uid, however, don't do so, because we don't
2613                        // want them internally to be re-ordered.
2614                        if (mLruProcesses.get(i-1).info.uid != uid) {
2615                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2616                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2617                            ProcessRecord tmp = mLruProcesses.get(i);
2618                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2619                            mLruProcesses.set(i-1, tmp);
2620                            i--;
2621                        }
2622                    } else {
2623                        // A gap, we can stop here.
2624                        break;
2625                    }
2626                }
2627            } else {
2628                // Process has activities, put it at the very tipsy-top.
2629                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2630                mLruProcesses.add(app);
2631            }
2632            nextIndex = mLruProcessServiceStart;
2633        } else if (hasService) {
2634            // Process has services, put it at the top of the service list.
2635            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2636            mLruProcesses.add(mLruProcessActivityStart, app);
2637            nextIndex = mLruProcessServiceStart;
2638            mLruProcessActivityStart++;
2639        } else  {
2640            // Process not otherwise of interest, it goes to the top of the non-service area.
2641            int index = mLruProcessServiceStart;
2642            if (client != null) {
2643                // If there is a client, don't allow the process to be moved up higher
2644                // in the list than that client.
2645                int clientIndex = mLruProcesses.lastIndexOf(client);
2646                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2647                        + " when updating " + app);
2648                if (clientIndex <= lrui) {
2649                    // Don't allow the client index restriction to push it down farther in the
2650                    // list than it already is.
2651                    clientIndex = lrui;
2652                }
2653                if (clientIndex >= 0 && index > clientIndex) {
2654                    index = clientIndex;
2655                }
2656            }
2657            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2658            mLruProcesses.add(index, app);
2659            nextIndex = index-1;
2660            mLruProcessActivityStart++;
2661            mLruProcessServiceStart++;
2662        }
2663
2664        // If the app is currently using a content provider or service,
2665        // bump those processes as well.
2666        for (int j=app.connections.size()-1; j>=0; j--) {
2667            ConnectionRecord cr = app.connections.valueAt(j);
2668            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2669                    && cr.binding.service.app != null
2670                    && cr.binding.service.app.lruSeq != mLruSeq
2671                    && !cr.binding.service.app.persistent) {
2672                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2673                        "service connection", cr, app);
2674            }
2675        }
2676        for (int j=app.conProviders.size()-1; j>=0; j--) {
2677            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2678            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2679                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2680                        "provider reference", cpr, app);
2681            }
2682        }
2683    }
2684
2685    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2686        if (uid == Process.SYSTEM_UID) {
2687            // The system gets to run in any process.  If there are multiple
2688            // processes with the same uid, just pick the first (this
2689            // should never happen).
2690            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2691            if (procs == null) return null;
2692            final int N = procs.size();
2693            for (int i = 0; i < N; i++) {
2694                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2695            }
2696        }
2697        ProcessRecord proc = mProcessNames.get(processName, uid);
2698        if (false && proc != null && !keepIfLarge
2699                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2700                && proc.lastCachedPss >= 4000) {
2701            // Turn this condition on to cause killing to happen regularly, for testing.
2702            if (proc.baseProcessTracker != null) {
2703                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2704            }
2705            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2706                    + "k from cached");
2707        } else if (proc != null && !keepIfLarge
2708                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2709                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2710            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2711            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2712                if (proc.baseProcessTracker != null) {
2713                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2714                }
2715                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2716                        + "k from cached");
2717            }
2718        }
2719        return proc;
2720    }
2721
2722    void ensurePackageDexOpt(String packageName) {
2723        IPackageManager pm = AppGlobals.getPackageManager();
2724        try {
2725            if (pm.performDexOpt(packageName)) {
2726                mDidDexOpt = true;
2727            }
2728        } catch (RemoteException e) {
2729        }
2730    }
2731
2732    boolean isNextTransitionForward() {
2733        int transit = mWindowManager.getPendingAppTransition();
2734        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2735                || transit == AppTransition.TRANSIT_TASK_OPEN
2736                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2737    }
2738
2739    final ProcessRecord startProcessLocked(String processName,
2740            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2741            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2742            boolean isolated, boolean keepIfLarge) {
2743        ProcessRecord app;
2744        if (!isolated) {
2745            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2746        } else {
2747            // If this is an isolated process, it can't re-use an existing process.
2748            app = null;
2749        }
2750        // We don't have to do anything more if:
2751        // (1) There is an existing application record; and
2752        // (2) The caller doesn't think it is dead, OR there is no thread
2753        //     object attached to it so we know it couldn't have crashed; and
2754        // (3) There is a pid assigned to it, so it is either starting or
2755        //     already running.
2756        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2757                + " app=" + app + " knownToBeDead=" + knownToBeDead
2758                + " thread=" + (app != null ? app.thread : null)
2759                + " pid=" + (app != null ? app.pid : -1));
2760        if (app != null && app.pid > 0) {
2761            if (!knownToBeDead || app.thread == null) {
2762                // We already have the app running, or are waiting for it to
2763                // come up (we have a pid but not yet its thread), so keep it.
2764                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2765                // If this is a new package in the process, add the package to the list
2766                app.addPackage(info.packageName, mProcessStats);
2767                return app;
2768            }
2769
2770            // An application record is attached to a previous process,
2771            // clean it up now.
2772            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2773            handleAppDiedLocked(app, true, true);
2774        }
2775
2776        String hostingNameStr = hostingName != null
2777                ? hostingName.flattenToShortString() : null;
2778
2779        if (!isolated) {
2780            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2781                // If we are in the background, then check to see if this process
2782                // is bad.  If so, we will just silently fail.
2783                if (mBadProcesses.get(info.processName, info.uid) != null) {
2784                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2785                            + "/" + info.processName);
2786                    return null;
2787                }
2788            } else {
2789                // When the user is explicitly starting a process, then clear its
2790                // crash count so that we won't make it bad until they see at
2791                // least one crash dialog again, and make the process good again
2792                // if it had been bad.
2793                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2794                        + "/" + info.processName);
2795                mProcessCrashTimes.remove(info.processName, info.uid);
2796                if (mBadProcesses.get(info.processName, info.uid) != null) {
2797                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2798                            UserHandle.getUserId(info.uid), info.uid,
2799                            info.processName);
2800                    mBadProcesses.remove(info.processName, info.uid);
2801                    if (app != null) {
2802                        app.bad = false;
2803                    }
2804                }
2805            }
2806        }
2807
2808        if (app == null) {
2809            app = newProcessRecordLocked(info, processName, isolated);
2810            if (app == null) {
2811                Slog.w(TAG, "Failed making new process record for "
2812                        + processName + "/" + info.uid + " isolated=" + isolated);
2813                return null;
2814            }
2815            mProcessNames.put(processName, app.uid, app);
2816            if (isolated) {
2817                mIsolatedProcesses.put(app.uid, app);
2818            }
2819        } else {
2820            // If this is a new package in the process, add the package to the list
2821            app.addPackage(info.packageName, mProcessStats);
2822        }
2823
2824        // If the system is not ready yet, then hold off on starting this
2825        // process until it is.
2826        if (!mProcessesReady
2827                && !isAllowedWhileBooting(info)
2828                && !allowWhileBooting) {
2829            if (!mProcessesOnHold.contains(app)) {
2830                mProcessesOnHold.add(app);
2831            }
2832            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2833            return app;
2834        }
2835
2836        startProcessLocked(app, hostingType, hostingNameStr);
2837        return (app.pid != 0) ? app : null;
2838    }
2839
2840    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2841        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2842    }
2843
2844    private final void startProcessLocked(ProcessRecord app,
2845            String hostingType, String hostingNameStr) {
2846        if (app.pid > 0 && app.pid != MY_PID) {
2847            synchronized (mPidsSelfLocked) {
2848                mPidsSelfLocked.remove(app.pid);
2849                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2850            }
2851            app.setPid(0);
2852        }
2853
2854        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2855                "startProcessLocked removing on hold: " + app);
2856        mProcessesOnHold.remove(app);
2857
2858        updateCpuStats();
2859
2860        try {
2861            int uid = app.uid;
2862
2863            int[] gids = null;
2864            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2865            if (!app.isolated) {
2866                int[] permGids = null;
2867                try {
2868                    final PackageManager pm = mContext.getPackageManager();
2869                    permGids = pm.getPackageGids(app.info.packageName);
2870
2871                    if (Environment.isExternalStorageEmulated()) {
2872                        if (pm.checkPermission(
2873                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2874                                app.info.packageName) == PERMISSION_GRANTED) {
2875                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2876                        } else {
2877                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2878                        }
2879                    }
2880                } catch (PackageManager.NameNotFoundException e) {
2881                    Slog.w(TAG, "Unable to retrieve gids", e);
2882                }
2883
2884                /*
2885                 * Add shared application GID so applications can share some
2886                 * resources like shared libraries
2887                 */
2888                if (permGids == null) {
2889                    gids = new int[1];
2890                } else {
2891                    gids = new int[permGids.length + 1];
2892                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2893                }
2894                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2895            }
2896            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2897                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2898                        && mTopComponent != null
2899                        && app.processName.equals(mTopComponent.getPackageName())) {
2900                    uid = 0;
2901                }
2902                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2903                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2904                    uid = 0;
2905                }
2906            }
2907            int debugFlags = 0;
2908            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2909                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2910                // Also turn on CheckJNI for debuggable apps. It's quite
2911                // awkward to turn on otherwise.
2912                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2913            }
2914            // Run the app in safe mode if its manifest requests so or the
2915            // system is booted in safe mode.
2916            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2917                mSafeMode == true) {
2918                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2919            }
2920            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2921                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2922            }
2923            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2924                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2925            }
2926            if ("1".equals(SystemProperties.get("debug.assert"))) {
2927                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2928            }
2929
2930            String requiredAbi = app.info.cpuAbi;
2931            if (requiredAbi == null) {
2932                requiredAbi = Build.SUPPORTED_ABIS[0];
2933            }
2934
2935            // Start the process.  It will either succeed and return a result containing
2936            // the PID of the new process, or else throw a RuntimeException.
2937            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2938                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2939                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2940
2941            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2942            synchronized (bs) {
2943                if (bs.isOnBattery()) {
2944                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2945                }
2946            }
2947
2948            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2949                    UserHandle.getUserId(uid), startResult.pid, uid,
2950                    app.processName, hostingType,
2951                    hostingNameStr != null ? hostingNameStr : "");
2952
2953            if (app.persistent) {
2954                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2955            }
2956
2957            StringBuilder buf = mStringBuilder;
2958            buf.setLength(0);
2959            buf.append("Start proc ");
2960            buf.append(app.processName);
2961            buf.append(" for ");
2962            buf.append(hostingType);
2963            if (hostingNameStr != null) {
2964                buf.append(" ");
2965                buf.append(hostingNameStr);
2966            }
2967            buf.append(": pid=");
2968            buf.append(startResult.pid);
2969            buf.append(" uid=");
2970            buf.append(uid);
2971            buf.append(" gids={");
2972            if (gids != null) {
2973                for (int gi=0; gi<gids.length; gi++) {
2974                    if (gi != 0) buf.append(", ");
2975                    buf.append(gids[gi]);
2976
2977                }
2978            }
2979            buf.append("}");
2980            Slog.i(TAG, buf.toString());
2981            app.setPid(startResult.pid);
2982            app.usingWrapper = startResult.usingWrapper;
2983            app.removed = false;
2984            synchronized (mPidsSelfLocked) {
2985                this.mPidsSelfLocked.put(startResult.pid, app);
2986                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2987                msg.obj = app;
2988                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2989                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2990            }
2991            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2992                    app.processName, app.info.uid);
2993            if (app.isolated) {
2994                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2995            }
2996        } catch (RuntimeException e) {
2997            // XXX do better error recovery.
2998            app.setPid(0);
2999            Slog.e(TAG, "Failure starting process " + app.processName, e);
3000        }
3001    }
3002
3003    void updateUsageStats(ActivityRecord component, boolean resumed) {
3004        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3005        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3006        if (resumed) {
3007            mUsageStatsService.noteResumeComponent(component.realActivity);
3008            synchronized (stats) {
3009                stats.noteActivityResumedLocked(component.app.uid);
3010            }
3011        } else {
3012            mUsageStatsService.notePauseComponent(component.realActivity);
3013            synchronized (stats) {
3014                stats.noteActivityPausedLocked(component.app.uid);
3015            }
3016        }
3017    }
3018
3019    Intent getHomeIntent() {
3020        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3021        intent.setComponent(mTopComponent);
3022        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3023            intent.addCategory(Intent.CATEGORY_HOME);
3024        }
3025        return intent;
3026    }
3027
3028    boolean startHomeActivityLocked(int userId) {
3029        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3030                && mTopAction == null) {
3031            // We are running in factory test mode, but unable to find
3032            // the factory test app, so just sit around displaying the
3033            // error message and don't try to start anything.
3034            return false;
3035        }
3036        Intent intent = getHomeIntent();
3037        ActivityInfo aInfo =
3038            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3039        if (aInfo != null) {
3040            intent.setComponent(new ComponentName(
3041                    aInfo.applicationInfo.packageName, aInfo.name));
3042            // Don't do this if the home app is currently being
3043            // instrumented.
3044            aInfo = new ActivityInfo(aInfo);
3045            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3046            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3047                    aInfo.applicationInfo.uid, true);
3048            if (app == null || app.instrumentationClass == null) {
3049                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3050                mStackSupervisor.startHomeActivity(intent, aInfo);
3051            }
3052        }
3053
3054        return true;
3055    }
3056
3057    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3058        ActivityInfo ai = null;
3059        ComponentName comp = intent.getComponent();
3060        try {
3061            if (comp != null) {
3062                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3063            } else {
3064                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3065                        intent,
3066                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3067                            flags, userId);
3068
3069                if (info != null) {
3070                    ai = info.activityInfo;
3071                }
3072            }
3073        } catch (RemoteException e) {
3074            // ignore
3075        }
3076
3077        return ai;
3078    }
3079
3080    /**
3081     * Starts the "new version setup screen" if appropriate.
3082     */
3083    void startSetupActivityLocked() {
3084        // Only do this once per boot.
3085        if (mCheckedForSetup) {
3086            return;
3087        }
3088
3089        // We will show this screen if the current one is a different
3090        // version than the last one shown, and we are not running in
3091        // low-level factory test mode.
3092        final ContentResolver resolver = mContext.getContentResolver();
3093        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3094                Settings.Global.getInt(resolver,
3095                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3096            mCheckedForSetup = true;
3097
3098            // See if we should be showing the platform update setup UI.
3099            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3100            List<ResolveInfo> ris = mContext.getPackageManager()
3101                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3102
3103            // We don't allow third party apps to replace this.
3104            ResolveInfo ri = null;
3105            for (int i=0; ris != null && i<ris.size(); i++) {
3106                if ((ris.get(i).activityInfo.applicationInfo.flags
3107                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3108                    ri = ris.get(i);
3109                    break;
3110                }
3111            }
3112
3113            if (ri != null) {
3114                String vers = ri.activityInfo.metaData != null
3115                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3116                        : null;
3117                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3118                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3119                            Intent.METADATA_SETUP_VERSION);
3120                }
3121                String lastVers = Settings.Secure.getString(
3122                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3123                if (vers != null && !vers.equals(lastVers)) {
3124                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3125                    intent.setComponent(new ComponentName(
3126                            ri.activityInfo.packageName, ri.activityInfo.name));
3127                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3128                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3129                }
3130            }
3131        }
3132    }
3133
3134    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3135        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3136    }
3137
3138    void enforceNotIsolatedCaller(String caller) {
3139        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3140            throw new SecurityException("Isolated process not allowed to call " + caller);
3141        }
3142    }
3143
3144    @Override
3145    public int getFrontActivityScreenCompatMode() {
3146        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3147        synchronized (this) {
3148            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3149        }
3150    }
3151
3152    @Override
3153    public void setFrontActivityScreenCompatMode(int mode) {
3154        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3155                "setFrontActivityScreenCompatMode");
3156        synchronized (this) {
3157            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3158        }
3159    }
3160
3161    @Override
3162    public int getPackageScreenCompatMode(String packageName) {
3163        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3164        synchronized (this) {
3165            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3166        }
3167    }
3168
3169    @Override
3170    public void setPackageScreenCompatMode(String packageName, int mode) {
3171        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3172                "setPackageScreenCompatMode");
3173        synchronized (this) {
3174            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3175        }
3176    }
3177
3178    @Override
3179    public boolean getPackageAskScreenCompat(String packageName) {
3180        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3181        synchronized (this) {
3182            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3183        }
3184    }
3185
3186    @Override
3187    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3188        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3189                "setPackageAskScreenCompat");
3190        synchronized (this) {
3191            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3192        }
3193    }
3194
3195    private void dispatchProcessesChanged() {
3196        int N;
3197        synchronized (this) {
3198            N = mPendingProcessChanges.size();
3199            if (mActiveProcessChanges.length < N) {
3200                mActiveProcessChanges = new ProcessChangeItem[N];
3201            }
3202            mPendingProcessChanges.toArray(mActiveProcessChanges);
3203            mAvailProcessChanges.addAll(mPendingProcessChanges);
3204            mPendingProcessChanges.clear();
3205            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3206        }
3207
3208        int i = mProcessObservers.beginBroadcast();
3209        while (i > 0) {
3210            i--;
3211            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3212            if (observer != null) {
3213                try {
3214                    for (int j=0; j<N; j++) {
3215                        ProcessChangeItem item = mActiveProcessChanges[j];
3216                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3217                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3218                                    + item.pid + " uid=" + item.uid + ": "
3219                                    + item.foregroundActivities);
3220                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3221                                    item.foregroundActivities);
3222                        }
3223                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3224                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3225                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3226                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3227                        }
3228                    }
3229                } catch (RemoteException e) {
3230                }
3231            }
3232        }
3233        mProcessObservers.finishBroadcast();
3234    }
3235
3236    private void dispatchProcessDied(int pid, int uid) {
3237        int i = mProcessObservers.beginBroadcast();
3238        while (i > 0) {
3239            i--;
3240            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3241            if (observer != null) {
3242                try {
3243                    observer.onProcessDied(pid, uid);
3244                } catch (RemoteException e) {
3245                }
3246            }
3247        }
3248        mProcessObservers.finishBroadcast();
3249    }
3250
3251    final void doPendingActivityLaunchesLocked(boolean doResume) {
3252        final int N = mPendingActivityLaunches.size();
3253        if (N <= 0) {
3254            return;
3255        }
3256        for (int i=0; i<N; i++) {
3257            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3258            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3259                    doResume && i == (N-1), null);
3260        }
3261        mPendingActivityLaunches.clear();
3262    }
3263
3264    @Override
3265    public final int startActivity(IApplicationThread caller, String callingPackage,
3266            Intent intent, String resolvedType, IBinder resultTo,
3267            String resultWho, int requestCode, int startFlags,
3268            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3269        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3270                resultWho, requestCode,
3271                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3272    }
3273
3274    @Override
3275    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3276            Intent intent, String resolvedType, IBinder resultTo,
3277            String resultWho, int requestCode, int startFlags,
3278            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3279        enforceNotIsolatedCaller("startActivity");
3280        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3281                false, true, "startActivity", null);
3282        // TODO: Switch to user app stacks here.
3283        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3284                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3285                null, null, options, userId, null);
3286    }
3287
3288    @Override
3289    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3290            Intent intent, String resolvedType, IBinder resultTo,
3291            String resultWho, int requestCode, int startFlags, String profileFile,
3292            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3293        enforceNotIsolatedCaller("startActivityAndWait");
3294        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3295                false, true, "startActivityAndWait", null);
3296        WaitResult res = new WaitResult();
3297        // TODO: Switch to user app stacks here.
3298        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3299                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3300                res, null, options, UserHandle.getCallingUserId(), null);
3301        return res;
3302    }
3303
3304    @Override
3305    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3306            Intent intent, String resolvedType, IBinder resultTo,
3307            String resultWho, int requestCode, int startFlags, Configuration config,
3308            Bundle options, int userId) {
3309        enforceNotIsolatedCaller("startActivityWithConfig");
3310        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3311                false, true, "startActivityWithConfig", null);
3312        // TODO: Switch to user app stacks here.
3313        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3314                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3315                null, null, null, config, options, userId, null);
3316        return ret;
3317    }
3318
3319    @Override
3320    public int startActivityIntentSender(IApplicationThread caller,
3321            IntentSender intent, Intent fillInIntent, String resolvedType,
3322            IBinder resultTo, String resultWho, int requestCode,
3323            int flagsMask, int flagsValues, Bundle options) {
3324        enforceNotIsolatedCaller("startActivityIntentSender");
3325        // Refuse possible leaked file descriptors
3326        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3327            throw new IllegalArgumentException("File descriptors passed in Intent");
3328        }
3329
3330        IIntentSender sender = intent.getTarget();
3331        if (!(sender instanceof PendingIntentRecord)) {
3332            throw new IllegalArgumentException("Bad PendingIntent object");
3333        }
3334
3335        PendingIntentRecord pir = (PendingIntentRecord)sender;
3336
3337        synchronized (this) {
3338            // If this is coming from the currently resumed activity, it is
3339            // effectively saying that app switches are allowed at this point.
3340            final ActivityStack stack = getFocusedStack();
3341            if (stack.mResumedActivity != null &&
3342                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3343                mAppSwitchesAllowedTime = 0;
3344            }
3345        }
3346        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3347                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3348        return ret;
3349    }
3350
3351    @Override
3352    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3353            Intent intent, String resolvedType, IVoiceInteractionSession session,
3354            IVoiceInteractor interactor, int startFlags, String profileFile,
3355            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3356        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3357                != PackageManager.PERMISSION_GRANTED) {
3358            String msg = "Permission Denial: startVoiceActivity() from pid="
3359                    + Binder.getCallingPid()
3360                    + ", uid=" + Binder.getCallingUid()
3361                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3362            Slog.w(TAG, msg);
3363            throw new SecurityException(msg);
3364        }
3365        if (session == null || interactor == null) {
3366            throw new NullPointerException("null session or interactor");
3367        }
3368        userId = handleIncomingUser(callingPid, callingUid, userId,
3369                false, true, "startVoiceActivity", null);
3370        // TODO: Switch to user app stacks here.
3371        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3372                resolvedType, session, interactor, null, null, 0, startFlags,
3373                profileFile, profileFd, null, null, options, userId, null);
3374    }
3375
3376    @Override
3377    public boolean startNextMatchingActivity(IBinder callingActivity,
3378            Intent intent, Bundle options) {
3379        // Refuse possible leaked file descriptors
3380        if (intent != null && intent.hasFileDescriptors() == true) {
3381            throw new IllegalArgumentException("File descriptors passed in Intent");
3382        }
3383
3384        synchronized (this) {
3385            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3386            if (r == null) {
3387                ActivityOptions.abort(options);
3388                return false;
3389            }
3390            if (r.app == null || r.app.thread == null) {
3391                // The caller is not running...  d'oh!
3392                ActivityOptions.abort(options);
3393                return false;
3394            }
3395            intent = new Intent(intent);
3396            // The caller is not allowed to change the data.
3397            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3398            // And we are resetting to find the next component...
3399            intent.setComponent(null);
3400
3401            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3402
3403            ActivityInfo aInfo = null;
3404            try {
3405                List<ResolveInfo> resolves =
3406                    AppGlobals.getPackageManager().queryIntentActivities(
3407                            intent, r.resolvedType,
3408                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3409                            UserHandle.getCallingUserId());
3410
3411                // Look for the original activity in the list...
3412                final int N = resolves != null ? resolves.size() : 0;
3413                for (int i=0; i<N; i++) {
3414                    ResolveInfo rInfo = resolves.get(i);
3415                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3416                            && rInfo.activityInfo.name.equals(r.info.name)) {
3417                        // We found the current one...  the next matching is
3418                        // after it.
3419                        i++;
3420                        if (i<N) {
3421                            aInfo = resolves.get(i).activityInfo;
3422                        }
3423                        if (debug) {
3424                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3425                                    + "/" + r.info.name);
3426                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3427                                    + "/" + aInfo.name);
3428                        }
3429                        break;
3430                    }
3431                }
3432            } catch (RemoteException e) {
3433            }
3434
3435            if (aInfo == null) {
3436                // Nobody who is next!
3437                ActivityOptions.abort(options);
3438                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3439                return false;
3440            }
3441
3442            intent.setComponent(new ComponentName(
3443                    aInfo.applicationInfo.packageName, aInfo.name));
3444            intent.setFlags(intent.getFlags()&~(
3445                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3446                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3447                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3448                    Intent.FLAG_ACTIVITY_NEW_TASK));
3449
3450            // Okay now we need to start the new activity, replacing the
3451            // currently running activity.  This is a little tricky because
3452            // we want to start the new one as if the current one is finished,
3453            // but not finish the current one first so that there is no flicker.
3454            // And thus...
3455            final boolean wasFinishing = r.finishing;
3456            r.finishing = true;
3457
3458            // Propagate reply information over to the new activity.
3459            final ActivityRecord resultTo = r.resultTo;
3460            final String resultWho = r.resultWho;
3461            final int requestCode = r.requestCode;
3462            r.resultTo = null;
3463            if (resultTo != null) {
3464                resultTo.removeResultsLocked(r, resultWho, requestCode);
3465            }
3466
3467            final long origId = Binder.clearCallingIdentity();
3468            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3469                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3470                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3471                    options, false, null, null);
3472            Binder.restoreCallingIdentity(origId);
3473
3474            r.finishing = wasFinishing;
3475            if (res != ActivityManager.START_SUCCESS) {
3476                return false;
3477            }
3478            return true;
3479        }
3480    }
3481
3482    final int startActivityInPackage(int uid, String callingPackage,
3483            Intent intent, String resolvedType, IBinder resultTo,
3484            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3485                    IActivityContainer container) {
3486
3487        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3488                false, true, "startActivityInPackage", null);
3489
3490        // TODO: Switch to user app stacks here.
3491        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3492                null, null, resultTo, resultWho, requestCode, startFlags,
3493                null, null, null, null, options, userId, container);
3494        return ret;
3495    }
3496
3497    @Override
3498    public final int startActivities(IApplicationThread caller, String callingPackage,
3499            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3500            int userId) {
3501        enforceNotIsolatedCaller("startActivities");
3502        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3503                false, true, "startActivity", null);
3504        // TODO: Switch to user app stacks here.
3505        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3506                resolvedTypes, resultTo, options, userId);
3507        return ret;
3508    }
3509
3510    final int startActivitiesInPackage(int uid, String callingPackage,
3511            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3512            Bundle options, int userId) {
3513
3514        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3515                false, true, "startActivityInPackage", null);
3516        // TODO: Switch to user app stacks here.
3517        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3518                resultTo, options, userId);
3519        return ret;
3520    }
3521
3522    final void addRecentTaskLocked(TaskRecord task) {
3523        int N = mRecentTasks.size();
3524        // Quick case: check if the top-most recent task is the same.
3525        if (N > 0 && mRecentTasks.get(0) == task) {
3526            return;
3527        }
3528        // Another quick case: never add voice sessions.
3529        if (task.voiceSession != null) {
3530            return;
3531        }
3532        // Remove any existing entries that are the same kind of task.
3533        final Intent intent = task.intent;
3534        final boolean document = intent != null && intent.isDocument();
3535        final ComponentName comp = intent.getComponent();
3536
3537        int maxRecents = task.maxRecents - 1;
3538        for (int i=0; i<N; i++) {
3539            TaskRecord tr = mRecentTasks.get(i);
3540            if (task != tr) {
3541                if (task.userId != tr.userId) {
3542                    continue;
3543                }
3544                final Intent trIntent = tr.intent;
3545                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3546                    (intent == null || !intent.filterEquals(trIntent))) {
3547                    continue;
3548                }
3549                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3550                if (document && trIsDocument) {
3551                    // These are the same document activity (not necessarily the same doc).
3552                    if (maxRecents > 0) {
3553                        --maxRecents;
3554                        continue;
3555                    }
3556                    // Hit the maximum number of documents for this task. Fall through
3557                    // and remove this document from recents.
3558                } else if (document || trIsDocument) {
3559                    // Only one of these is a document. Not the droid we're looking for.
3560                    continue;
3561                }
3562            }
3563
3564            // Either task and tr are the same or, their affinities match or their intents match
3565            // and neither of them is a document, or they are documents using the same activity
3566            // and their maxRecents has been reached.
3567            tr.disposeThumbnail();
3568            mRecentTasks.remove(i);
3569            i--;
3570            N--;
3571            if (task.intent == null) {
3572                // If the new recent task we are adding is not fully
3573                // specified, then replace it with the existing recent task.
3574                task = tr;
3575            }
3576            mTaskPersister.notify(tr, false);
3577        }
3578        if (N >= MAX_RECENT_TASKS) {
3579            mRecentTasks.remove(N-1).disposeThumbnail();
3580        }
3581        mRecentTasks.add(0, task);
3582    }
3583
3584    @Override
3585    public void reportActivityFullyDrawn(IBinder token) {
3586        synchronized (this) {
3587            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3588            if (r == null) {
3589                return;
3590            }
3591            r.reportFullyDrawnLocked();
3592        }
3593    }
3594
3595    @Override
3596    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3597        synchronized (this) {
3598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3599            if (r == null) {
3600                return;
3601            }
3602            final long origId = Binder.clearCallingIdentity();
3603            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3604            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3605                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3606            if (config != null) {
3607                r.frozenBeforeDestroy = true;
3608                if (!updateConfigurationLocked(config, r, false, false)) {
3609                    mStackSupervisor.resumeTopActivitiesLocked();
3610                }
3611            }
3612            Binder.restoreCallingIdentity(origId);
3613        }
3614    }
3615
3616    @Override
3617    public int getRequestedOrientation(IBinder token) {
3618        synchronized (this) {
3619            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3620            if (r == null) {
3621                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3622            }
3623            return mWindowManager.getAppOrientation(r.appToken);
3624        }
3625    }
3626
3627    /**
3628     * This is the internal entry point for handling Activity.finish().
3629     *
3630     * @param token The Binder token referencing the Activity we want to finish.
3631     * @param resultCode Result code, if any, from this Activity.
3632     * @param resultData Result data (Intent), if any, from this Activity.
3633     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3634     *            the root Activity in the task.
3635     *
3636     * @return Returns true if the activity successfully finished, or false if it is still running.
3637     */
3638    @Override
3639    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3640            boolean finishTask) {
3641        // Refuse possible leaked file descriptors
3642        if (resultData != null && resultData.hasFileDescriptors() == true) {
3643            throw new IllegalArgumentException("File descriptors passed in Intent");
3644        }
3645
3646        synchronized(this) {
3647            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3648            if (r == null) {
3649                return true;
3650            }
3651            // Keep track of the root activity of the task before we finish it
3652            TaskRecord tr = r.task;
3653            ActivityRecord rootR = tr.getRootActivity();
3654            if (mController != null) {
3655                // Find the first activity that is not finishing.
3656                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3657                if (next != null) {
3658                    // ask watcher if this is allowed
3659                    boolean resumeOK = true;
3660                    try {
3661                        resumeOK = mController.activityResuming(next.packageName);
3662                    } catch (RemoteException e) {
3663                        mController = null;
3664                        Watchdog.getInstance().setActivityController(null);
3665                    }
3666
3667                    if (!resumeOK) {
3668                        return false;
3669                    }
3670                }
3671            }
3672            final long origId = Binder.clearCallingIdentity();
3673            try {
3674                boolean res;
3675                if (finishTask && r == rootR) {
3676                    // If requested, remove the task that is associated to this activity only if it
3677                    // was the root activity in the task.  The result code and data is ignored because
3678                    // we don't support returning them across task boundaries.
3679                    res = removeTaskByIdLocked(tr.taskId, 0);
3680                } else {
3681                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3682                            resultData, "app-request", true);
3683                }
3684                return res;
3685            } finally {
3686                Binder.restoreCallingIdentity(origId);
3687            }
3688        }
3689    }
3690
3691    @Override
3692    public final void finishHeavyWeightApp() {
3693        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3694                != PackageManager.PERMISSION_GRANTED) {
3695            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3696                    + Binder.getCallingPid()
3697                    + ", uid=" + Binder.getCallingUid()
3698                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3699            Slog.w(TAG, msg);
3700            throw new SecurityException(msg);
3701        }
3702
3703        synchronized(this) {
3704            if (mHeavyWeightProcess == null) {
3705                return;
3706            }
3707
3708            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3709                    mHeavyWeightProcess.activities);
3710            for (int i=0; i<activities.size(); i++) {
3711                ActivityRecord r = activities.get(i);
3712                if (!r.finishing) {
3713                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3714                            null, "finish-heavy", true);
3715                }
3716            }
3717
3718            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3719                    mHeavyWeightProcess.userId, 0));
3720            mHeavyWeightProcess = null;
3721        }
3722    }
3723
3724    @Override
3725    public void crashApplication(int uid, int initialPid, String packageName,
3726            String message) {
3727        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3728                != PackageManager.PERMISSION_GRANTED) {
3729            String msg = "Permission Denial: crashApplication() from pid="
3730                    + Binder.getCallingPid()
3731                    + ", uid=" + Binder.getCallingUid()
3732                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3733            Slog.w(TAG, msg);
3734            throw new SecurityException(msg);
3735        }
3736
3737        synchronized(this) {
3738            ProcessRecord proc = null;
3739
3740            // Figure out which process to kill.  We don't trust that initialPid
3741            // still has any relation to current pids, so must scan through the
3742            // list.
3743            synchronized (mPidsSelfLocked) {
3744                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3745                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3746                    if (p.uid != uid) {
3747                        continue;
3748                    }
3749                    if (p.pid == initialPid) {
3750                        proc = p;
3751                        break;
3752                    }
3753                    if (p.pkgList.containsKey(packageName)) {
3754                        proc = p;
3755                    }
3756                }
3757            }
3758
3759            if (proc == null) {
3760                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3761                        + " initialPid=" + initialPid
3762                        + " packageName=" + packageName);
3763                return;
3764            }
3765
3766            if (proc.thread != null) {
3767                if (proc.pid == Process.myPid()) {
3768                    Log.w(TAG, "crashApplication: trying to crash self!");
3769                    return;
3770                }
3771                long ident = Binder.clearCallingIdentity();
3772                try {
3773                    proc.thread.scheduleCrash(message);
3774                } catch (RemoteException e) {
3775                }
3776                Binder.restoreCallingIdentity(ident);
3777            }
3778        }
3779    }
3780
3781    @Override
3782    public final void finishSubActivity(IBinder token, String resultWho,
3783            int requestCode) {
3784        synchronized(this) {
3785            final long origId = Binder.clearCallingIdentity();
3786            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3787            if (r != null) {
3788                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3789            }
3790            Binder.restoreCallingIdentity(origId);
3791        }
3792    }
3793
3794    @Override
3795    public boolean finishActivityAffinity(IBinder token) {
3796        synchronized(this) {
3797            final long origId = Binder.clearCallingIdentity();
3798            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3799            boolean res = false;
3800            if (r != null) {
3801                res = r.task.stack.finishActivityAffinityLocked(r);
3802            }
3803            Binder.restoreCallingIdentity(origId);
3804            return res;
3805        }
3806    }
3807
3808    @Override
3809    public boolean willActivityBeVisible(IBinder token) {
3810        synchronized(this) {
3811            ActivityStack stack = ActivityRecord.getStackLocked(token);
3812            if (stack != null) {
3813                return stack.willActivityBeVisibleLocked(token);
3814            }
3815            return false;
3816        }
3817    }
3818
3819    @Override
3820    public void overridePendingTransition(IBinder token, String packageName,
3821            int enterAnim, int exitAnim) {
3822        synchronized(this) {
3823            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3824            if (self == null) {
3825                return;
3826            }
3827
3828            final long origId = Binder.clearCallingIdentity();
3829
3830            if (self.state == ActivityState.RESUMED
3831                    || self.state == ActivityState.PAUSING) {
3832                mWindowManager.overridePendingAppTransition(packageName,
3833                        enterAnim, exitAnim, null);
3834            }
3835
3836            Binder.restoreCallingIdentity(origId);
3837        }
3838    }
3839
3840    /**
3841     * Main function for removing an existing process from the activity manager
3842     * as a result of that process going away.  Clears out all connections
3843     * to the process.
3844     */
3845    private final void handleAppDiedLocked(ProcessRecord app,
3846            boolean restarting, boolean allowRestart) {
3847        int pid = app.pid;
3848        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3849        if (!restarting) {
3850            removeLruProcessLocked(app);
3851            if (pid > 0) {
3852                ProcessList.remove(pid);
3853            }
3854        }
3855
3856        if (mProfileProc == app) {
3857            clearProfilerLocked();
3858        }
3859
3860        // Remove this application's activities from active lists.
3861        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3862
3863        app.activities.clear();
3864
3865        if (app.instrumentationClass != null) {
3866            Slog.w(TAG, "Crash of app " + app.processName
3867                  + " running instrumentation " + app.instrumentationClass);
3868            Bundle info = new Bundle();
3869            info.putString("shortMsg", "Process crashed.");
3870            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3871        }
3872
3873        if (!restarting) {
3874            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3875                // If there was nothing to resume, and we are not already
3876                // restarting this process, but there is a visible activity that
3877                // is hosted by the process...  then make sure all visible
3878                // activities are running, taking care of restarting this
3879                // process.
3880                if (hasVisibleActivities) {
3881                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3882                }
3883            }
3884        }
3885    }
3886
3887    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3888        IBinder threadBinder = thread.asBinder();
3889        // Find the application record.
3890        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3891            ProcessRecord rec = mLruProcesses.get(i);
3892            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3893                return i;
3894            }
3895        }
3896        return -1;
3897    }
3898
3899    final ProcessRecord getRecordForAppLocked(
3900            IApplicationThread thread) {
3901        if (thread == null) {
3902            return null;
3903        }
3904
3905        int appIndex = getLRURecordIndexForAppLocked(thread);
3906        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3907    }
3908
3909    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3910        // If there are no longer any background processes running,
3911        // and the app that died was not running instrumentation,
3912        // then tell everyone we are now low on memory.
3913        boolean haveBg = false;
3914        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3915            ProcessRecord rec = mLruProcesses.get(i);
3916            if (rec.thread != null
3917                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3918                haveBg = true;
3919                break;
3920            }
3921        }
3922
3923        if (!haveBg) {
3924            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3925            if (doReport) {
3926                long now = SystemClock.uptimeMillis();
3927                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3928                    doReport = false;
3929                } else {
3930                    mLastMemUsageReportTime = now;
3931                }
3932            }
3933            final ArrayList<ProcessMemInfo> memInfos
3934                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3935            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3936            long now = SystemClock.uptimeMillis();
3937            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3938                ProcessRecord rec = mLruProcesses.get(i);
3939                if (rec == dyingProc || rec.thread == null) {
3940                    continue;
3941                }
3942                if (doReport) {
3943                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3944                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3945                }
3946                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3947                    // The low memory report is overriding any current
3948                    // state for a GC request.  Make sure to do
3949                    // heavy/important/visible/foreground processes first.
3950                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3951                        rec.lastRequestedGc = 0;
3952                    } else {
3953                        rec.lastRequestedGc = rec.lastLowMemory;
3954                    }
3955                    rec.reportLowMemory = true;
3956                    rec.lastLowMemory = now;
3957                    mProcessesToGc.remove(rec);
3958                    addProcessToGcListLocked(rec);
3959                }
3960            }
3961            if (doReport) {
3962                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3963                mHandler.sendMessage(msg);
3964            }
3965            scheduleAppGcsLocked();
3966        }
3967    }
3968
3969    final void appDiedLocked(ProcessRecord app, int pid,
3970            IApplicationThread thread) {
3971
3972        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3973        synchronized (stats) {
3974            stats.noteProcessDiedLocked(app.info.uid, pid);
3975        }
3976
3977        // Clean up already done if the process has been re-started.
3978        if (app.pid == pid && app.thread != null &&
3979                app.thread.asBinder() == thread.asBinder()) {
3980            boolean doLowMem = app.instrumentationClass == null;
3981            boolean doOomAdj = doLowMem;
3982            if (!app.killedByAm) {
3983                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3984                        + ") has died.");
3985                mAllowLowerMemLevel = true;
3986            } else {
3987                // Note that we always want to do oom adj to update our state with the
3988                // new number of procs.
3989                mAllowLowerMemLevel = false;
3990                doLowMem = false;
3991            }
3992            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3993            if (DEBUG_CLEANUP) Slog.v(
3994                TAG, "Dying app: " + app + ", pid: " + pid
3995                + ", thread: " + thread.asBinder());
3996            handleAppDiedLocked(app, false, true);
3997
3998            if (doOomAdj) {
3999                updateOomAdjLocked();
4000            }
4001            if (doLowMem) {
4002                doLowMemReportIfNeededLocked(app);
4003            }
4004        } else if (app.pid != pid) {
4005            // A new process has already been started.
4006            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4007                    + ") has died and restarted (pid " + app.pid + ").");
4008            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4009        } else if (DEBUG_PROCESSES) {
4010            Slog.d(TAG, "Received spurious death notification for thread "
4011                    + thread.asBinder());
4012        }
4013    }
4014
4015    /**
4016     * If a stack trace dump file is configured, dump process stack traces.
4017     * @param clearTraces causes the dump file to be erased prior to the new
4018     *    traces being written, if true; when false, the new traces will be
4019     *    appended to any existing file content.
4020     * @param firstPids of dalvik VM processes to dump stack traces for first
4021     * @param lastPids of dalvik VM processes to dump stack traces for last
4022     * @param nativeProcs optional list of native process names to dump stack crawls
4023     * @return file containing stack traces, or null if no dump file is configured
4024     */
4025    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4026            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4027        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4028        if (tracesPath == null || tracesPath.length() == 0) {
4029            return null;
4030        }
4031
4032        File tracesFile = new File(tracesPath);
4033        try {
4034            File tracesDir = tracesFile.getParentFile();
4035            if (!tracesDir.exists()) {
4036                tracesFile.mkdirs();
4037                if (!SELinux.restorecon(tracesDir)) {
4038                    return null;
4039                }
4040            }
4041            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4042
4043            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4044            tracesFile.createNewFile();
4045            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4046        } catch (IOException e) {
4047            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4048            return null;
4049        }
4050
4051        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4052        return tracesFile;
4053    }
4054
4055    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4056            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4057        // Use a FileObserver to detect when traces finish writing.
4058        // The order of traces is considered important to maintain for legibility.
4059        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4060            @Override
4061            public synchronized void onEvent(int event, String path) { notify(); }
4062        };
4063
4064        try {
4065            observer.startWatching();
4066
4067            // First collect all of the stacks of the most important pids.
4068            if (firstPids != null) {
4069                try {
4070                    int num = firstPids.size();
4071                    for (int i = 0; i < num; i++) {
4072                        synchronized (observer) {
4073                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4074                            observer.wait(200);  // Wait for write-close, give up after 200msec
4075                        }
4076                    }
4077                } catch (InterruptedException e) {
4078                    Log.wtf(TAG, e);
4079                }
4080            }
4081
4082            // Next collect the stacks of the native pids
4083            if (nativeProcs != null) {
4084                int[] pids = Process.getPidsForCommands(nativeProcs);
4085                if (pids != null) {
4086                    for (int pid : pids) {
4087                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4088                    }
4089                }
4090            }
4091
4092            // Lastly, measure CPU usage.
4093            if (processCpuTracker != null) {
4094                processCpuTracker.init();
4095                System.gc();
4096                processCpuTracker.update();
4097                try {
4098                    synchronized (processCpuTracker) {
4099                        processCpuTracker.wait(500); // measure over 1/2 second.
4100                    }
4101                } catch (InterruptedException e) {
4102                }
4103                processCpuTracker.update();
4104
4105                // We'll take the stack crawls of just the top apps using CPU.
4106                final int N = processCpuTracker.countWorkingStats();
4107                int numProcs = 0;
4108                for (int i=0; i<N && numProcs<5; i++) {
4109                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4110                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4111                        numProcs++;
4112                        try {
4113                            synchronized (observer) {
4114                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4115                                observer.wait(200);  // Wait for write-close, give up after 200msec
4116                            }
4117                        } catch (InterruptedException e) {
4118                            Log.wtf(TAG, e);
4119                        }
4120
4121                    }
4122                }
4123            }
4124        } finally {
4125            observer.stopWatching();
4126        }
4127    }
4128
4129    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4130        if (true || IS_USER_BUILD) {
4131            return;
4132        }
4133        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4134        if (tracesPath == null || tracesPath.length() == 0) {
4135            return;
4136        }
4137
4138        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4139        StrictMode.allowThreadDiskWrites();
4140        try {
4141            final File tracesFile = new File(tracesPath);
4142            final File tracesDir = tracesFile.getParentFile();
4143            final File tracesTmp = new File(tracesDir, "__tmp__");
4144            try {
4145                if (!tracesDir.exists()) {
4146                    tracesFile.mkdirs();
4147                    if (!SELinux.restorecon(tracesDir.getPath())) {
4148                        return;
4149                    }
4150                }
4151                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4152
4153                if (tracesFile.exists()) {
4154                    tracesTmp.delete();
4155                    tracesFile.renameTo(tracesTmp);
4156                }
4157                StringBuilder sb = new StringBuilder();
4158                Time tobj = new Time();
4159                tobj.set(System.currentTimeMillis());
4160                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4161                sb.append(": ");
4162                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4163                sb.append(" since ");
4164                sb.append(msg);
4165                FileOutputStream fos = new FileOutputStream(tracesFile);
4166                fos.write(sb.toString().getBytes());
4167                if (app == null) {
4168                    fos.write("\n*** No application process!".getBytes());
4169                }
4170                fos.close();
4171                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4172            } catch (IOException e) {
4173                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4174                return;
4175            }
4176
4177            if (app != null) {
4178                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4179                firstPids.add(app.pid);
4180                dumpStackTraces(tracesPath, firstPids, null, null, null);
4181            }
4182
4183            File lastTracesFile = null;
4184            File curTracesFile = null;
4185            for (int i=9; i>=0; i--) {
4186                String name = String.format(Locale.US, "slow%02d.txt", i);
4187                curTracesFile = new File(tracesDir, name);
4188                if (curTracesFile.exists()) {
4189                    if (lastTracesFile != null) {
4190                        curTracesFile.renameTo(lastTracesFile);
4191                    } else {
4192                        curTracesFile.delete();
4193                    }
4194                }
4195                lastTracesFile = curTracesFile;
4196            }
4197            tracesFile.renameTo(curTracesFile);
4198            if (tracesTmp.exists()) {
4199                tracesTmp.renameTo(tracesFile);
4200            }
4201        } finally {
4202            StrictMode.setThreadPolicy(oldPolicy);
4203        }
4204    }
4205
4206    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4207            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4208        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4209        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4210
4211        if (mController != null) {
4212            try {
4213                // 0 == continue, -1 = kill process immediately
4214                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4215                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4216            } catch (RemoteException e) {
4217                mController = null;
4218                Watchdog.getInstance().setActivityController(null);
4219            }
4220        }
4221
4222        long anrTime = SystemClock.uptimeMillis();
4223        if (MONITOR_CPU_USAGE) {
4224            updateCpuStatsNow();
4225        }
4226
4227        synchronized (this) {
4228            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4229            if (mShuttingDown) {
4230                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4231                return;
4232            } else if (app.notResponding) {
4233                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4234                return;
4235            } else if (app.crashing) {
4236                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4237                return;
4238            }
4239
4240            // In case we come through here for the same app before completing
4241            // this one, mark as anring now so we will bail out.
4242            app.notResponding = true;
4243
4244            // Log the ANR to the event log.
4245            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4246                    app.processName, app.info.flags, annotation);
4247
4248            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4249            firstPids.add(app.pid);
4250
4251            int parentPid = app.pid;
4252            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4253            if (parentPid != app.pid) firstPids.add(parentPid);
4254
4255            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4256
4257            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4258                ProcessRecord r = mLruProcesses.get(i);
4259                if (r != null && r.thread != null) {
4260                    int pid = r.pid;
4261                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4262                        if (r.persistent) {
4263                            firstPids.add(pid);
4264                        } else {
4265                            lastPids.put(pid, Boolean.TRUE);
4266                        }
4267                    }
4268                }
4269            }
4270        }
4271
4272        // Log the ANR to the main log.
4273        StringBuilder info = new StringBuilder();
4274        info.setLength(0);
4275        info.append("ANR in ").append(app.processName);
4276        if (activity != null && activity.shortComponentName != null) {
4277            info.append(" (").append(activity.shortComponentName).append(")");
4278        }
4279        info.append("\n");
4280        info.append("PID: ").append(app.pid).append("\n");
4281        if (annotation != null) {
4282            info.append("Reason: ").append(annotation).append("\n");
4283        }
4284        if (parent != null && parent != activity) {
4285            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4286        }
4287
4288        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4289
4290        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4291                NATIVE_STACKS_OF_INTEREST);
4292
4293        String cpuInfo = null;
4294        if (MONITOR_CPU_USAGE) {
4295            updateCpuStatsNow();
4296            synchronized (mProcessCpuThread) {
4297                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4298            }
4299            info.append(processCpuTracker.printCurrentLoad());
4300            info.append(cpuInfo);
4301        }
4302
4303        info.append(processCpuTracker.printCurrentState(anrTime));
4304
4305        Slog.e(TAG, info.toString());
4306        if (tracesFile == null) {
4307            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4308            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4309        }
4310
4311        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4312                cpuInfo, tracesFile, null);
4313
4314        if (mController != null) {
4315            try {
4316                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4317                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4318                if (res != 0) {
4319                    if (res < 0 && app.pid != MY_PID) {
4320                        Process.killProcess(app.pid);
4321                    } else {
4322                        synchronized (this) {
4323                            mServices.scheduleServiceTimeoutLocked(app);
4324                        }
4325                    }
4326                    return;
4327                }
4328            } catch (RemoteException e) {
4329                mController = null;
4330                Watchdog.getInstance().setActivityController(null);
4331            }
4332        }
4333
4334        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4335        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4336                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4337
4338        synchronized (this) {
4339            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4340                killUnneededProcessLocked(app, "background ANR");
4341                return;
4342            }
4343
4344            // Set the app's notResponding state, and look up the errorReportReceiver
4345            makeAppNotRespondingLocked(app,
4346                    activity != null ? activity.shortComponentName : null,
4347                    annotation != null ? "ANR " + annotation : "ANR",
4348                    info.toString());
4349
4350            // Bring up the infamous App Not Responding dialog
4351            Message msg = Message.obtain();
4352            HashMap<String, Object> map = new HashMap<String, Object>();
4353            msg.what = SHOW_NOT_RESPONDING_MSG;
4354            msg.obj = map;
4355            msg.arg1 = aboveSystem ? 1 : 0;
4356            map.put("app", app);
4357            if (activity != null) {
4358                map.put("activity", activity);
4359            }
4360
4361            mHandler.sendMessage(msg);
4362        }
4363    }
4364
4365    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4366        if (!mLaunchWarningShown) {
4367            mLaunchWarningShown = true;
4368            mHandler.post(new Runnable() {
4369                @Override
4370                public void run() {
4371                    synchronized (ActivityManagerService.this) {
4372                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4373                        d.show();
4374                        mHandler.postDelayed(new Runnable() {
4375                            @Override
4376                            public void run() {
4377                                synchronized (ActivityManagerService.this) {
4378                                    d.dismiss();
4379                                    mLaunchWarningShown = false;
4380                                }
4381                            }
4382                        }, 4000);
4383                    }
4384                }
4385            });
4386        }
4387    }
4388
4389    @Override
4390    public boolean clearApplicationUserData(final String packageName,
4391            final IPackageDataObserver observer, int userId) {
4392        enforceNotIsolatedCaller("clearApplicationUserData");
4393        int uid = Binder.getCallingUid();
4394        int pid = Binder.getCallingPid();
4395        userId = handleIncomingUser(pid, uid,
4396                userId, false, true, "clearApplicationUserData", null);
4397        long callingId = Binder.clearCallingIdentity();
4398        try {
4399            IPackageManager pm = AppGlobals.getPackageManager();
4400            int pkgUid = -1;
4401            synchronized(this) {
4402                try {
4403                    pkgUid = pm.getPackageUid(packageName, userId);
4404                } catch (RemoteException e) {
4405                }
4406                if (pkgUid == -1) {
4407                    Slog.w(TAG, "Invalid packageName: " + packageName);
4408                    if (observer != null) {
4409                        try {
4410                            observer.onRemoveCompleted(packageName, false);
4411                        } catch (RemoteException e) {
4412                            Slog.i(TAG, "Observer no longer exists.");
4413                        }
4414                    }
4415                    return false;
4416                }
4417                if (uid == pkgUid || checkComponentPermission(
4418                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4419                        pid, uid, -1, true)
4420                        == PackageManager.PERMISSION_GRANTED) {
4421                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4422                } else {
4423                    throw new SecurityException("PID " + pid + " does not have permission "
4424                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4425                                    + " of package " + packageName);
4426                }
4427            }
4428
4429            try {
4430                // Clear application user data
4431                pm.clearApplicationUserData(packageName, observer, userId);
4432
4433                // Remove all permissions granted from/to this package
4434                removeUriPermissionsForPackageLocked(packageName, userId, true);
4435
4436                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4437                        Uri.fromParts("package", packageName, null));
4438                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4439                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4440                        null, null, 0, null, null, null, false, false, userId);
4441            } catch (RemoteException e) {
4442            }
4443        } finally {
4444            Binder.restoreCallingIdentity(callingId);
4445        }
4446        return true;
4447    }
4448
4449    @Override
4450    public void killBackgroundProcesses(final String packageName, int userId) {
4451        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4452                != PackageManager.PERMISSION_GRANTED &&
4453                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4454                        != PackageManager.PERMISSION_GRANTED) {
4455            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4456                    + Binder.getCallingPid()
4457                    + ", uid=" + Binder.getCallingUid()
4458                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4459            Slog.w(TAG, msg);
4460            throw new SecurityException(msg);
4461        }
4462
4463        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4464                userId, true, true, "killBackgroundProcesses", null);
4465        long callingId = Binder.clearCallingIdentity();
4466        try {
4467            IPackageManager pm = AppGlobals.getPackageManager();
4468            synchronized(this) {
4469                int appId = -1;
4470                try {
4471                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4472                } catch (RemoteException e) {
4473                }
4474                if (appId == -1) {
4475                    Slog.w(TAG, "Invalid packageName: " + packageName);
4476                    return;
4477                }
4478                killPackageProcessesLocked(packageName, appId, userId,
4479                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4480            }
4481        } finally {
4482            Binder.restoreCallingIdentity(callingId);
4483        }
4484    }
4485
4486    @Override
4487    public void killAllBackgroundProcesses() {
4488        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4489                != PackageManager.PERMISSION_GRANTED) {
4490            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4491                    + Binder.getCallingPid()
4492                    + ", uid=" + Binder.getCallingUid()
4493                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4494            Slog.w(TAG, msg);
4495            throw new SecurityException(msg);
4496        }
4497
4498        long callingId = Binder.clearCallingIdentity();
4499        try {
4500            synchronized(this) {
4501                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4502                final int NP = mProcessNames.getMap().size();
4503                for (int ip=0; ip<NP; ip++) {
4504                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4505                    final int NA = apps.size();
4506                    for (int ia=0; ia<NA; ia++) {
4507                        ProcessRecord app = apps.valueAt(ia);
4508                        if (app.persistent) {
4509                            // we don't kill persistent processes
4510                            continue;
4511                        }
4512                        if (app.removed) {
4513                            procs.add(app);
4514                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4515                            app.removed = true;
4516                            procs.add(app);
4517                        }
4518                    }
4519                }
4520
4521                int N = procs.size();
4522                for (int i=0; i<N; i++) {
4523                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4524                }
4525                mAllowLowerMemLevel = true;
4526                updateOomAdjLocked();
4527                doLowMemReportIfNeededLocked(null);
4528            }
4529        } finally {
4530            Binder.restoreCallingIdentity(callingId);
4531        }
4532    }
4533
4534    @Override
4535    public void forceStopPackage(final String packageName, int userId) {
4536        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4537                != PackageManager.PERMISSION_GRANTED) {
4538            String msg = "Permission Denial: forceStopPackage() from pid="
4539                    + Binder.getCallingPid()
4540                    + ", uid=" + Binder.getCallingUid()
4541                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4542            Slog.w(TAG, msg);
4543            throw new SecurityException(msg);
4544        }
4545        final int callingPid = Binder.getCallingPid();
4546        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4547                userId, true, true, "forceStopPackage", null);
4548        long callingId = Binder.clearCallingIdentity();
4549        try {
4550            IPackageManager pm = AppGlobals.getPackageManager();
4551            synchronized(this) {
4552                int[] users = userId == UserHandle.USER_ALL
4553                        ? getUsersLocked() : new int[] { userId };
4554                for (int user : users) {
4555                    int pkgUid = -1;
4556                    try {
4557                        pkgUid = pm.getPackageUid(packageName, user);
4558                    } catch (RemoteException e) {
4559                    }
4560                    if (pkgUid == -1) {
4561                        Slog.w(TAG, "Invalid packageName: " + packageName);
4562                        continue;
4563                    }
4564                    try {
4565                        pm.setPackageStoppedState(packageName, true, user);
4566                    } catch (RemoteException e) {
4567                    } catch (IllegalArgumentException e) {
4568                        Slog.w(TAG, "Failed trying to unstop package "
4569                                + packageName + ": " + e);
4570                    }
4571                    if (isUserRunningLocked(user, false)) {
4572                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4573                    }
4574                }
4575            }
4576        } finally {
4577            Binder.restoreCallingIdentity(callingId);
4578        }
4579    }
4580
4581    /*
4582     * The pkg name and app id have to be specified.
4583     */
4584    @Override
4585    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4586        if (pkg == null) {
4587            return;
4588        }
4589        // Make sure the uid is valid.
4590        if (appid < 0) {
4591            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4592            return;
4593        }
4594        int callerUid = Binder.getCallingUid();
4595        // Only the system server can kill an application
4596        if (callerUid == Process.SYSTEM_UID) {
4597            // Post an aysnc message to kill the application
4598            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4599            msg.arg1 = appid;
4600            msg.arg2 = 0;
4601            Bundle bundle = new Bundle();
4602            bundle.putString("pkg", pkg);
4603            bundle.putString("reason", reason);
4604            msg.obj = bundle;
4605            mHandler.sendMessage(msg);
4606        } else {
4607            throw new SecurityException(callerUid + " cannot kill pkg: " +
4608                    pkg);
4609        }
4610    }
4611
4612    @Override
4613    public void closeSystemDialogs(String reason) {
4614        enforceNotIsolatedCaller("closeSystemDialogs");
4615
4616        final int pid = Binder.getCallingPid();
4617        final int uid = Binder.getCallingUid();
4618        final long origId = Binder.clearCallingIdentity();
4619        try {
4620            synchronized (this) {
4621                // Only allow this from foreground processes, so that background
4622                // applications can't abuse it to prevent system UI from being shown.
4623                if (uid >= Process.FIRST_APPLICATION_UID) {
4624                    ProcessRecord proc;
4625                    synchronized (mPidsSelfLocked) {
4626                        proc = mPidsSelfLocked.get(pid);
4627                    }
4628                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4629                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4630                                + " from background process " + proc);
4631                        return;
4632                    }
4633                }
4634                closeSystemDialogsLocked(reason);
4635            }
4636        } finally {
4637            Binder.restoreCallingIdentity(origId);
4638        }
4639    }
4640
4641    void closeSystemDialogsLocked(String reason) {
4642        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4643        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4644                | Intent.FLAG_RECEIVER_FOREGROUND);
4645        if (reason != null) {
4646            intent.putExtra("reason", reason);
4647        }
4648        mWindowManager.closeSystemDialogs(reason);
4649
4650        mStackSupervisor.closeSystemDialogsLocked();
4651
4652        broadcastIntentLocked(null, null, intent, null,
4653                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4654                Process.SYSTEM_UID, UserHandle.USER_ALL);
4655    }
4656
4657    @Override
4658    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4659        enforceNotIsolatedCaller("getProcessMemoryInfo");
4660        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4661        for (int i=pids.length-1; i>=0; i--) {
4662            ProcessRecord proc;
4663            int oomAdj;
4664            synchronized (this) {
4665                synchronized (mPidsSelfLocked) {
4666                    proc = mPidsSelfLocked.get(pids[i]);
4667                    oomAdj = proc != null ? proc.setAdj : 0;
4668                }
4669            }
4670            infos[i] = new Debug.MemoryInfo();
4671            Debug.getMemoryInfo(pids[i], infos[i]);
4672            if (proc != null) {
4673                synchronized (this) {
4674                    if (proc.thread != null && proc.setAdj == oomAdj) {
4675                        // Record this for posterity if the process has been stable.
4676                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4677                                infos[i].getTotalUss(), false, proc.pkgList);
4678                    }
4679                }
4680            }
4681        }
4682        return infos;
4683    }
4684
4685    @Override
4686    public long[] getProcessPss(int[] pids) {
4687        enforceNotIsolatedCaller("getProcessPss");
4688        long[] pss = new long[pids.length];
4689        for (int i=pids.length-1; i>=0; i--) {
4690            ProcessRecord proc;
4691            int oomAdj;
4692            synchronized (this) {
4693                synchronized (mPidsSelfLocked) {
4694                    proc = mPidsSelfLocked.get(pids[i]);
4695                    oomAdj = proc != null ? proc.setAdj : 0;
4696                }
4697            }
4698            long[] tmpUss = new long[1];
4699            pss[i] = Debug.getPss(pids[i], tmpUss);
4700            if (proc != null) {
4701                synchronized (this) {
4702                    if (proc.thread != null && proc.setAdj == oomAdj) {
4703                        // Record this for posterity if the process has been stable.
4704                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4705                    }
4706                }
4707            }
4708        }
4709        return pss;
4710    }
4711
4712    @Override
4713    public void killApplicationProcess(String processName, int uid) {
4714        if (processName == null) {
4715            return;
4716        }
4717
4718        int callerUid = Binder.getCallingUid();
4719        // Only the system server can kill an application
4720        if (callerUid == Process.SYSTEM_UID) {
4721            synchronized (this) {
4722                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4723                if (app != null && app.thread != null) {
4724                    try {
4725                        app.thread.scheduleSuicide();
4726                    } catch (RemoteException e) {
4727                        // If the other end already died, then our work here is done.
4728                    }
4729                } else {
4730                    Slog.w(TAG, "Process/uid not found attempting kill of "
4731                            + processName + " / " + uid);
4732                }
4733            }
4734        } else {
4735            throw new SecurityException(callerUid + " cannot kill app process: " +
4736                    processName);
4737        }
4738    }
4739
4740    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4741        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4742                false, true, false, false, UserHandle.getUserId(uid), reason);
4743        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4744                Uri.fromParts("package", packageName, null));
4745        if (!mProcessesReady) {
4746            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4747                    | Intent.FLAG_RECEIVER_FOREGROUND);
4748        }
4749        intent.putExtra(Intent.EXTRA_UID, uid);
4750        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4751        broadcastIntentLocked(null, null, intent,
4752                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4753                false, false,
4754                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4755    }
4756
4757    private void forceStopUserLocked(int userId, String reason) {
4758        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4759        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4760        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4761                | Intent.FLAG_RECEIVER_FOREGROUND);
4762        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4763        broadcastIntentLocked(null, null, intent,
4764                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4765                false, false,
4766                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4767    }
4768
4769    private final boolean killPackageProcessesLocked(String packageName, int appId,
4770            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4771            boolean doit, boolean evenPersistent, String reason) {
4772        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4773
4774        // Remove all processes this package may have touched: all with the
4775        // same UID (except for the system or root user), and all whose name
4776        // matches the package name.
4777        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4778        final int NP = mProcessNames.getMap().size();
4779        for (int ip=0; ip<NP; ip++) {
4780            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4781            final int NA = apps.size();
4782            for (int ia=0; ia<NA; ia++) {
4783                ProcessRecord app = apps.valueAt(ia);
4784                if (app.persistent && !evenPersistent) {
4785                    // we don't kill persistent processes
4786                    continue;
4787                }
4788                if (app.removed) {
4789                    if (doit) {
4790                        procs.add(app);
4791                    }
4792                    continue;
4793                }
4794
4795                // Skip process if it doesn't meet our oom adj requirement.
4796                if (app.setAdj < minOomAdj) {
4797                    continue;
4798                }
4799
4800                // If no package is specified, we call all processes under the
4801                // give user id.
4802                if (packageName == null) {
4803                    if (app.userId != userId) {
4804                        continue;
4805                    }
4806                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4807                        continue;
4808                    }
4809                // Package has been specified, we want to hit all processes
4810                // that match it.  We need to qualify this by the processes
4811                // that are running under the specified app and user ID.
4812                } else {
4813                    if (UserHandle.getAppId(app.uid) != appId) {
4814                        continue;
4815                    }
4816                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4817                        continue;
4818                    }
4819                    if (!app.pkgList.containsKey(packageName)) {
4820                        continue;
4821                    }
4822                }
4823
4824                // Process has passed all conditions, kill it!
4825                if (!doit) {
4826                    return true;
4827                }
4828                app.removed = true;
4829                procs.add(app);
4830            }
4831        }
4832
4833        int N = procs.size();
4834        for (int i=0; i<N; i++) {
4835            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4836        }
4837        updateOomAdjLocked();
4838        return N > 0;
4839    }
4840
4841    private final boolean forceStopPackageLocked(String name, int appId,
4842            boolean callerWillRestart, boolean purgeCache, boolean doit,
4843            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4844        int i;
4845        int N;
4846
4847        if (userId == UserHandle.USER_ALL && name == null) {
4848            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4849        }
4850
4851        if (appId < 0 && name != null) {
4852            try {
4853                appId = UserHandle.getAppId(
4854                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4855            } catch (RemoteException e) {
4856            }
4857        }
4858
4859        if (doit) {
4860            if (name != null) {
4861                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4862                        + " user=" + userId + ": " + reason);
4863            } else {
4864                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4865            }
4866
4867            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4868            for (int ip=pmap.size()-1; ip>=0; ip--) {
4869                SparseArray<Long> ba = pmap.valueAt(ip);
4870                for (i=ba.size()-1; i>=0; i--) {
4871                    boolean remove = false;
4872                    final int entUid = ba.keyAt(i);
4873                    if (name != null) {
4874                        if (userId == UserHandle.USER_ALL) {
4875                            if (UserHandle.getAppId(entUid) == appId) {
4876                                remove = true;
4877                            }
4878                        } else {
4879                            if (entUid == UserHandle.getUid(userId, appId)) {
4880                                remove = true;
4881                            }
4882                        }
4883                    } else if (UserHandle.getUserId(entUid) == userId) {
4884                        remove = true;
4885                    }
4886                    if (remove) {
4887                        ba.removeAt(i);
4888                    }
4889                }
4890                if (ba.size() == 0) {
4891                    pmap.removeAt(ip);
4892                }
4893            }
4894        }
4895
4896        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4897                -100, callerWillRestart, true, doit, evenPersistent,
4898                name == null ? ("stop user " + userId) : ("stop " + name));
4899
4900        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4901            if (!doit) {
4902                return true;
4903            }
4904            didSomething = true;
4905        }
4906
4907        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4908            if (!doit) {
4909                return true;
4910            }
4911            didSomething = true;
4912        }
4913
4914        if (name == null) {
4915            // Remove all sticky broadcasts from this user.
4916            mStickyBroadcasts.remove(userId);
4917        }
4918
4919        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4920        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4921                userId, providers)) {
4922            if (!doit) {
4923                return true;
4924            }
4925            didSomething = true;
4926        }
4927        N = providers.size();
4928        for (i=0; i<N; i++) {
4929            removeDyingProviderLocked(null, providers.get(i), true);
4930        }
4931
4932        // Remove transient permissions granted from/to this package/user
4933        removeUriPermissionsForPackageLocked(name, userId, false);
4934
4935        if (name == null || uninstalling) {
4936            // Remove pending intents.  For now we only do this when force
4937            // stopping users, because we have some problems when doing this
4938            // for packages -- app widgets are not currently cleaned up for
4939            // such packages, so they can be left with bad pending intents.
4940            if (mIntentSenderRecords.size() > 0) {
4941                Iterator<WeakReference<PendingIntentRecord>> it
4942                        = mIntentSenderRecords.values().iterator();
4943                while (it.hasNext()) {
4944                    WeakReference<PendingIntentRecord> wpir = it.next();
4945                    if (wpir == null) {
4946                        it.remove();
4947                        continue;
4948                    }
4949                    PendingIntentRecord pir = wpir.get();
4950                    if (pir == null) {
4951                        it.remove();
4952                        continue;
4953                    }
4954                    if (name == null) {
4955                        // Stopping user, remove all objects for the user.
4956                        if (pir.key.userId != userId) {
4957                            // Not the same user, skip it.
4958                            continue;
4959                        }
4960                    } else {
4961                        if (UserHandle.getAppId(pir.uid) != appId) {
4962                            // Different app id, skip it.
4963                            continue;
4964                        }
4965                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4966                            // Different user, skip it.
4967                            continue;
4968                        }
4969                        if (!pir.key.packageName.equals(name)) {
4970                            // Different package, skip it.
4971                            continue;
4972                        }
4973                    }
4974                    if (!doit) {
4975                        return true;
4976                    }
4977                    didSomething = true;
4978                    it.remove();
4979                    pir.canceled = true;
4980                    if (pir.key.activity != null) {
4981                        pir.key.activity.pendingResults.remove(pir.ref);
4982                    }
4983                }
4984            }
4985        }
4986
4987        if (doit) {
4988            if (purgeCache && name != null) {
4989                AttributeCache ac = AttributeCache.instance();
4990                if (ac != null) {
4991                    ac.removePackage(name);
4992                }
4993            }
4994            if (mBooted) {
4995                mStackSupervisor.resumeTopActivitiesLocked();
4996                mStackSupervisor.scheduleIdleLocked();
4997            }
4998        }
4999
5000        return didSomething;
5001    }
5002
5003    private final boolean removeProcessLocked(ProcessRecord app,
5004            boolean callerWillRestart, boolean allowRestart, String reason) {
5005        final String name = app.processName;
5006        final int uid = app.uid;
5007        if (DEBUG_PROCESSES) Slog.d(
5008            TAG, "Force removing proc " + app.toShortString() + " (" + name
5009            + "/" + uid + ")");
5010
5011        mProcessNames.remove(name, uid);
5012        mIsolatedProcesses.remove(app.uid);
5013        if (mHeavyWeightProcess == app) {
5014            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5015                    mHeavyWeightProcess.userId, 0));
5016            mHeavyWeightProcess = null;
5017        }
5018        boolean needRestart = false;
5019        if (app.pid > 0 && app.pid != MY_PID) {
5020            int pid = app.pid;
5021            synchronized (mPidsSelfLocked) {
5022                mPidsSelfLocked.remove(pid);
5023                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5024            }
5025            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5026                    app.processName, app.info.uid);
5027            if (app.isolated) {
5028                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5029            }
5030            killUnneededProcessLocked(app, reason);
5031            handleAppDiedLocked(app, true, allowRestart);
5032            removeLruProcessLocked(app);
5033
5034            if (app.persistent && !app.isolated) {
5035                if (!callerWillRestart) {
5036                    addAppLocked(app.info, false);
5037                } else {
5038                    needRestart = true;
5039                }
5040            }
5041        } else {
5042            mRemovedProcesses.add(app);
5043        }
5044
5045        return needRestart;
5046    }
5047
5048    private final void processStartTimedOutLocked(ProcessRecord app) {
5049        final int pid = app.pid;
5050        boolean gone = false;
5051        synchronized (mPidsSelfLocked) {
5052            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5053            if (knownApp != null && knownApp.thread == null) {
5054                mPidsSelfLocked.remove(pid);
5055                gone = true;
5056            }
5057        }
5058
5059        if (gone) {
5060            Slog.w(TAG, "Process " + app + " failed to attach");
5061            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5062                    pid, app.uid, app.processName);
5063            mProcessNames.remove(app.processName, app.uid);
5064            mIsolatedProcesses.remove(app.uid);
5065            if (mHeavyWeightProcess == app) {
5066                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5067                        mHeavyWeightProcess.userId, 0));
5068                mHeavyWeightProcess = null;
5069            }
5070            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5071                    app.processName, app.info.uid);
5072            if (app.isolated) {
5073                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5074            }
5075            // Take care of any launching providers waiting for this process.
5076            checkAppInLaunchingProvidersLocked(app, true);
5077            // Take care of any services that are waiting for the process.
5078            mServices.processStartTimedOutLocked(app);
5079            killUnneededProcessLocked(app, "start timeout");
5080            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5081                Slog.w(TAG, "Unattached app died before backup, skipping");
5082                try {
5083                    IBackupManager bm = IBackupManager.Stub.asInterface(
5084                            ServiceManager.getService(Context.BACKUP_SERVICE));
5085                    bm.agentDisconnected(app.info.packageName);
5086                } catch (RemoteException e) {
5087                    // Can't happen; the backup manager is local
5088                }
5089            }
5090            if (isPendingBroadcastProcessLocked(pid)) {
5091                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5092                skipPendingBroadcastLocked(pid);
5093            }
5094        } else {
5095            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5096        }
5097    }
5098
5099    private final boolean attachApplicationLocked(IApplicationThread thread,
5100            int pid) {
5101
5102        // Find the application record that is being attached...  either via
5103        // the pid if we are running in multiple processes, or just pull the
5104        // next app record if we are emulating process with anonymous threads.
5105        ProcessRecord app;
5106        if (pid != MY_PID && pid >= 0) {
5107            synchronized (mPidsSelfLocked) {
5108                app = mPidsSelfLocked.get(pid);
5109            }
5110        } else {
5111            app = null;
5112        }
5113
5114        if (app == null) {
5115            Slog.w(TAG, "No pending application record for pid " + pid
5116                    + " (IApplicationThread " + thread + "); dropping process");
5117            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5118            if (pid > 0 && pid != MY_PID) {
5119                Process.killProcessQuiet(pid);
5120            } else {
5121                try {
5122                    thread.scheduleExit();
5123                } catch (Exception e) {
5124                    // Ignore exceptions.
5125                }
5126            }
5127            return false;
5128        }
5129
5130        // If this application record is still attached to a previous
5131        // process, clean it up now.
5132        if (app.thread != null) {
5133            handleAppDiedLocked(app, true, true);
5134        }
5135
5136        // Tell the process all about itself.
5137
5138        if (localLOGV) Slog.v(
5139                TAG, "Binding process pid " + pid + " to record " + app);
5140
5141        final String processName = app.processName;
5142        try {
5143            AppDeathRecipient adr = new AppDeathRecipient(
5144                    app, pid, thread);
5145            thread.asBinder().linkToDeath(adr, 0);
5146            app.deathRecipient = adr;
5147        } catch (RemoteException e) {
5148            app.resetPackageList(mProcessStats);
5149            startProcessLocked(app, "link fail", processName);
5150            return false;
5151        }
5152
5153        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5154
5155        app.makeActive(thread, mProcessStats);
5156        app.curAdj = app.setAdj = -100;
5157        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5158        app.forcingToForeground = null;
5159        updateProcessForegroundLocked(app, false, false);
5160        app.hasShownUi = false;
5161        app.debugging = false;
5162        app.cached = false;
5163
5164        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5165
5166        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5167        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5168
5169        if (!normalMode) {
5170            Slog.i(TAG, "Launching preboot mode app: " + app);
5171        }
5172
5173        if (localLOGV) Slog.v(
5174            TAG, "New app record " + app
5175            + " thread=" + thread.asBinder() + " pid=" + pid);
5176        try {
5177            int testMode = IApplicationThread.DEBUG_OFF;
5178            if (mDebugApp != null && mDebugApp.equals(processName)) {
5179                testMode = mWaitForDebugger
5180                    ? IApplicationThread.DEBUG_WAIT
5181                    : IApplicationThread.DEBUG_ON;
5182                app.debugging = true;
5183                if (mDebugTransient) {
5184                    mDebugApp = mOrigDebugApp;
5185                    mWaitForDebugger = mOrigWaitForDebugger;
5186                }
5187            }
5188            String profileFile = app.instrumentationProfileFile;
5189            ParcelFileDescriptor profileFd = null;
5190            boolean profileAutoStop = false;
5191            if (mProfileApp != null && mProfileApp.equals(processName)) {
5192                mProfileProc = app;
5193                profileFile = mProfileFile;
5194                profileFd = mProfileFd;
5195                profileAutoStop = mAutoStopProfiler;
5196            }
5197            boolean enableOpenGlTrace = false;
5198            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5199                enableOpenGlTrace = true;
5200                mOpenGlTraceApp = null;
5201            }
5202
5203            // If the app is being launched for restore or full backup, set it up specially
5204            boolean isRestrictedBackupMode = false;
5205            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5206                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5207                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5208                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5209            }
5210
5211            ensurePackageDexOpt(app.instrumentationInfo != null
5212                    ? app.instrumentationInfo.packageName
5213                    : app.info.packageName);
5214            if (app.instrumentationClass != null) {
5215                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5216            }
5217            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5218                    + processName + " with config " + mConfiguration);
5219            ApplicationInfo appInfo = app.instrumentationInfo != null
5220                    ? app.instrumentationInfo : app.info;
5221            app.compat = compatibilityInfoForPackageLocked(appInfo);
5222            if (profileFd != null) {
5223                profileFd = profileFd.dup();
5224            }
5225            thread.bindApplication(processName, appInfo, providers,
5226                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5227                    app.instrumentationArguments, app.instrumentationWatcher,
5228                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5229                    isRestrictedBackupMode || !normalMode, app.persistent,
5230                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5231                    mCoreSettingsObserver.getCoreSettingsLocked());
5232            updateLruProcessLocked(app, false, null);
5233            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5234        } catch (Exception e) {
5235            // todo: Yikes!  What should we do?  For now we will try to
5236            // start another process, but that could easily get us in
5237            // an infinite loop of restarting processes...
5238            Slog.w(TAG, "Exception thrown during bind!", e);
5239
5240            app.resetPackageList(mProcessStats);
5241            app.unlinkDeathRecipient();
5242            startProcessLocked(app, "bind fail", processName);
5243            return false;
5244        }
5245
5246        // Remove this record from the list of starting applications.
5247        mPersistentStartingProcesses.remove(app);
5248        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5249                "Attach application locked removing on hold: " + app);
5250        mProcessesOnHold.remove(app);
5251
5252        boolean badApp = false;
5253        boolean didSomething = false;
5254
5255        // See if the top visible activity is waiting to run in this process...
5256        if (normalMode) {
5257            try {
5258                if (mStackSupervisor.attachApplicationLocked(app)) {
5259                    didSomething = true;
5260                }
5261            } catch (Exception e) {
5262                badApp = true;
5263            }
5264        }
5265
5266        // Find any services that should be running in this process...
5267        if (!badApp) {
5268            try {
5269                didSomething |= mServices.attachApplicationLocked(app, processName);
5270            } catch (Exception e) {
5271                badApp = true;
5272            }
5273        }
5274
5275        // Check if a next-broadcast receiver is in this process...
5276        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5277            try {
5278                didSomething |= sendPendingBroadcastsLocked(app);
5279            } catch (Exception e) {
5280                // If the app died trying to launch the receiver we declare it 'bad'
5281                badApp = true;
5282            }
5283        }
5284
5285        // Check whether the next backup agent is in this process...
5286        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5287            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5288            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5289            try {
5290                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5291                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5292                        mBackupTarget.backupMode);
5293            } catch (Exception e) {
5294                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5295                e.printStackTrace();
5296            }
5297        }
5298
5299        if (badApp) {
5300            // todo: Also need to kill application to deal with all
5301            // kinds of exceptions.
5302            handleAppDiedLocked(app, false, true);
5303            return false;
5304        }
5305
5306        if (!didSomething) {
5307            updateOomAdjLocked();
5308        }
5309
5310        return true;
5311    }
5312
5313    @Override
5314    public final void attachApplication(IApplicationThread thread) {
5315        synchronized (this) {
5316            int callingPid = Binder.getCallingPid();
5317            final long origId = Binder.clearCallingIdentity();
5318            attachApplicationLocked(thread, callingPid);
5319            Binder.restoreCallingIdentity(origId);
5320        }
5321    }
5322
5323    @Override
5324    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5325        final long origId = Binder.clearCallingIdentity();
5326        synchronized (this) {
5327            ActivityStack stack = ActivityRecord.getStackLocked(token);
5328            if (stack != null) {
5329                ActivityRecord r =
5330                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5331                if (stopProfiling) {
5332                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5333                        try {
5334                            mProfileFd.close();
5335                        } catch (IOException e) {
5336                        }
5337                        clearProfilerLocked();
5338                    }
5339                }
5340            }
5341        }
5342        Binder.restoreCallingIdentity(origId);
5343    }
5344
5345    void enableScreenAfterBoot() {
5346        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5347                SystemClock.uptimeMillis());
5348        mWindowManager.enableScreenAfterBoot();
5349
5350        synchronized (this) {
5351            updateEventDispatchingLocked();
5352        }
5353    }
5354
5355    @Override
5356    public void showBootMessage(final CharSequence msg, final boolean always) {
5357        enforceNotIsolatedCaller("showBootMessage");
5358        mWindowManager.showBootMessage(msg, always);
5359    }
5360
5361    @Override
5362    public void dismissKeyguardOnNextActivity() {
5363        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5364        final long token = Binder.clearCallingIdentity();
5365        try {
5366            synchronized (this) {
5367                if (DEBUG_LOCKSCREEN) logLockScreen("");
5368                if (mLockScreenShown) {
5369                    mLockScreenShown = false;
5370                    comeOutOfSleepIfNeededLocked();
5371                }
5372                mStackSupervisor.setDismissKeyguard(true);
5373            }
5374        } finally {
5375            Binder.restoreCallingIdentity(token);
5376        }
5377    }
5378
5379    final void finishBooting() {
5380        // Register receivers to handle package update events
5381        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5382
5383        synchronized (this) {
5384            // Ensure that any processes we had put on hold are now started
5385            // up.
5386            final int NP = mProcessesOnHold.size();
5387            if (NP > 0) {
5388                ArrayList<ProcessRecord> procs =
5389                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5390                for (int ip=0; ip<NP; ip++) {
5391                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5392                            + procs.get(ip));
5393                    startProcessLocked(procs.get(ip), "on-hold", null);
5394                }
5395            }
5396
5397            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5398                // Start looking for apps that are abusing wake locks.
5399                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5400                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5401                // Tell anyone interested that we are done booting!
5402                SystemProperties.set("sys.boot_completed", "1");
5403                SystemProperties.set("dev.bootcomplete", "1");
5404                for (int i=0; i<mStartedUsers.size(); i++) {
5405                    UserStartedState uss = mStartedUsers.valueAt(i);
5406                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5407                        uss.mState = UserStartedState.STATE_RUNNING;
5408                        final int userId = mStartedUsers.keyAt(i);
5409                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5410                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5411                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5412                        broadcastIntentLocked(null, null, intent, null,
5413                                new IIntentReceiver.Stub() {
5414                                    @Override
5415                                    public void performReceive(Intent intent, int resultCode,
5416                                            String data, Bundle extras, boolean ordered,
5417                                            boolean sticky, int sendingUser) {
5418                                        synchronized (ActivityManagerService.this) {
5419                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5420                                                    true, false);
5421                                        }
5422                                    }
5423                                },
5424                                0, null, null,
5425                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5426                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5427                                userId);
5428                    }
5429                }
5430                scheduleStartProfilesLocked();
5431            }
5432        }
5433    }
5434
5435    final void ensureBootCompleted() {
5436        boolean booting;
5437        boolean enableScreen;
5438        synchronized (this) {
5439            booting = mBooting;
5440            mBooting = false;
5441            enableScreen = !mBooted;
5442            mBooted = true;
5443        }
5444
5445        if (booting) {
5446            finishBooting();
5447        }
5448
5449        if (enableScreen) {
5450            enableScreenAfterBoot();
5451        }
5452    }
5453
5454    @Override
5455    public final void activityResumed(IBinder token) {
5456        final long origId = Binder.clearCallingIdentity();
5457        synchronized(this) {
5458            ActivityStack stack = ActivityRecord.getStackLocked(token);
5459            if (stack != null) {
5460                ActivityRecord.activityResumedLocked(token);
5461            }
5462        }
5463        Binder.restoreCallingIdentity(origId);
5464    }
5465
5466    @Override
5467    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5468        final long origId = Binder.clearCallingIdentity();
5469        synchronized(this) {
5470            ActivityStack stack = ActivityRecord.getStackLocked(token);
5471            if (stack != null) {
5472                stack.activityPausedLocked(token, false, persistentState);
5473            }
5474        }
5475        Binder.restoreCallingIdentity(origId);
5476    }
5477
5478    @Override
5479    public final void activityStopped(IBinder token, Bundle icicle,
5480            PersistableBundle persistentState, CharSequence description) {
5481        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5482
5483        // Refuse possible leaked file descriptors
5484        if (icicle != null && icicle.hasFileDescriptors()) {
5485            throw new IllegalArgumentException("File descriptors passed in Bundle");
5486        }
5487
5488        final long origId = Binder.clearCallingIdentity();
5489
5490        synchronized (this) {
5491            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5492            if (r != null) {
5493                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5494            }
5495        }
5496
5497        trimApplications();
5498
5499        Binder.restoreCallingIdentity(origId);
5500    }
5501
5502    @Override
5503    public final void activityDestroyed(IBinder token) {
5504        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5505        synchronized (this) {
5506            ActivityStack stack = ActivityRecord.getStackLocked(token);
5507            if (stack != null) {
5508                stack.activityDestroyedLocked(token);
5509            }
5510        }
5511    }
5512
5513    @Override
5514    public String getCallingPackage(IBinder token) {
5515        synchronized (this) {
5516            ActivityRecord r = getCallingRecordLocked(token);
5517            return r != null ? r.info.packageName : null;
5518        }
5519    }
5520
5521    @Override
5522    public ComponentName getCallingActivity(IBinder token) {
5523        synchronized (this) {
5524            ActivityRecord r = getCallingRecordLocked(token);
5525            return r != null ? r.intent.getComponent() : null;
5526        }
5527    }
5528
5529    private ActivityRecord getCallingRecordLocked(IBinder token) {
5530        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5531        if (r == null) {
5532            return null;
5533        }
5534        return r.resultTo;
5535    }
5536
5537    @Override
5538    public ComponentName getActivityClassForToken(IBinder token) {
5539        synchronized(this) {
5540            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5541            if (r == null) {
5542                return null;
5543            }
5544            return r.intent.getComponent();
5545        }
5546    }
5547
5548    @Override
5549    public String getPackageForToken(IBinder token) {
5550        synchronized(this) {
5551            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5552            if (r == null) {
5553                return null;
5554            }
5555            return r.packageName;
5556        }
5557    }
5558
5559    @Override
5560    public IIntentSender getIntentSender(int type,
5561            String packageName, IBinder token, String resultWho,
5562            int requestCode, Intent[] intents, String[] resolvedTypes,
5563            int flags, Bundle options, int userId) {
5564        enforceNotIsolatedCaller("getIntentSender");
5565        // Refuse possible leaked file descriptors
5566        if (intents != null) {
5567            if (intents.length < 1) {
5568                throw new IllegalArgumentException("Intents array length must be >= 1");
5569            }
5570            for (int i=0; i<intents.length; i++) {
5571                Intent intent = intents[i];
5572                if (intent != null) {
5573                    if (intent.hasFileDescriptors()) {
5574                        throw new IllegalArgumentException("File descriptors passed in Intent");
5575                    }
5576                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5577                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5578                        throw new IllegalArgumentException(
5579                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5580                    }
5581                    intents[i] = new Intent(intent);
5582                }
5583            }
5584            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5585                throw new IllegalArgumentException(
5586                        "Intent array length does not match resolvedTypes length");
5587            }
5588        }
5589        if (options != null) {
5590            if (options.hasFileDescriptors()) {
5591                throw new IllegalArgumentException("File descriptors passed in options");
5592            }
5593        }
5594
5595        synchronized(this) {
5596            int callingUid = Binder.getCallingUid();
5597            int origUserId = userId;
5598            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5599                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5600                    "getIntentSender", null);
5601            if (origUserId == UserHandle.USER_CURRENT) {
5602                // We don't want to evaluate this until the pending intent is
5603                // actually executed.  However, we do want to always do the
5604                // security checking for it above.
5605                userId = UserHandle.USER_CURRENT;
5606            }
5607            try {
5608                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5609                    int uid = AppGlobals.getPackageManager()
5610                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5611                    if (!UserHandle.isSameApp(callingUid, uid)) {
5612                        String msg = "Permission Denial: getIntentSender() from pid="
5613                            + Binder.getCallingPid()
5614                            + ", uid=" + Binder.getCallingUid()
5615                            + ", (need uid=" + uid + ")"
5616                            + " is not allowed to send as package " + packageName;
5617                        Slog.w(TAG, msg);
5618                        throw new SecurityException(msg);
5619                    }
5620                }
5621
5622                return getIntentSenderLocked(type, packageName, callingUid, userId,
5623                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5624
5625            } catch (RemoteException e) {
5626                throw new SecurityException(e);
5627            }
5628        }
5629    }
5630
5631    IIntentSender getIntentSenderLocked(int type, String packageName,
5632            int callingUid, int userId, IBinder token, String resultWho,
5633            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5634            Bundle options) {
5635        if (DEBUG_MU)
5636            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5637        ActivityRecord activity = null;
5638        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5639            activity = ActivityRecord.isInStackLocked(token);
5640            if (activity == null) {
5641                return null;
5642            }
5643            if (activity.finishing) {
5644                return null;
5645            }
5646        }
5647
5648        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5649        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5650        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5651        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5652                |PendingIntent.FLAG_UPDATE_CURRENT);
5653
5654        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5655                type, packageName, activity, resultWho,
5656                requestCode, intents, resolvedTypes, flags, options, userId);
5657        WeakReference<PendingIntentRecord> ref;
5658        ref = mIntentSenderRecords.get(key);
5659        PendingIntentRecord rec = ref != null ? ref.get() : null;
5660        if (rec != null) {
5661            if (!cancelCurrent) {
5662                if (updateCurrent) {
5663                    if (rec.key.requestIntent != null) {
5664                        rec.key.requestIntent.replaceExtras(intents != null ?
5665                                intents[intents.length - 1] : null);
5666                    }
5667                    if (intents != null) {
5668                        intents[intents.length-1] = rec.key.requestIntent;
5669                        rec.key.allIntents = intents;
5670                        rec.key.allResolvedTypes = resolvedTypes;
5671                    } else {
5672                        rec.key.allIntents = null;
5673                        rec.key.allResolvedTypes = null;
5674                    }
5675                }
5676                return rec;
5677            }
5678            rec.canceled = true;
5679            mIntentSenderRecords.remove(key);
5680        }
5681        if (noCreate) {
5682            return rec;
5683        }
5684        rec = new PendingIntentRecord(this, key, callingUid);
5685        mIntentSenderRecords.put(key, rec.ref);
5686        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5687            if (activity.pendingResults == null) {
5688                activity.pendingResults
5689                        = new HashSet<WeakReference<PendingIntentRecord>>();
5690            }
5691            activity.pendingResults.add(rec.ref);
5692        }
5693        return rec;
5694    }
5695
5696    @Override
5697    public void cancelIntentSender(IIntentSender sender) {
5698        if (!(sender instanceof PendingIntentRecord)) {
5699            return;
5700        }
5701        synchronized(this) {
5702            PendingIntentRecord rec = (PendingIntentRecord)sender;
5703            try {
5704                int uid = AppGlobals.getPackageManager()
5705                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5706                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5707                    String msg = "Permission Denial: cancelIntentSender() from pid="
5708                        + Binder.getCallingPid()
5709                        + ", uid=" + Binder.getCallingUid()
5710                        + " is not allowed to cancel packges "
5711                        + rec.key.packageName;
5712                    Slog.w(TAG, msg);
5713                    throw new SecurityException(msg);
5714                }
5715            } catch (RemoteException e) {
5716                throw new SecurityException(e);
5717            }
5718            cancelIntentSenderLocked(rec, true);
5719        }
5720    }
5721
5722    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5723        rec.canceled = true;
5724        mIntentSenderRecords.remove(rec.key);
5725        if (cleanActivity && rec.key.activity != null) {
5726            rec.key.activity.pendingResults.remove(rec.ref);
5727        }
5728    }
5729
5730    @Override
5731    public String getPackageForIntentSender(IIntentSender pendingResult) {
5732        if (!(pendingResult instanceof PendingIntentRecord)) {
5733            return null;
5734        }
5735        try {
5736            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5737            return res.key.packageName;
5738        } catch (ClassCastException e) {
5739        }
5740        return null;
5741    }
5742
5743    @Override
5744    public int getUidForIntentSender(IIntentSender sender) {
5745        if (sender instanceof PendingIntentRecord) {
5746            try {
5747                PendingIntentRecord res = (PendingIntentRecord)sender;
5748                return res.uid;
5749            } catch (ClassCastException e) {
5750            }
5751        }
5752        return -1;
5753    }
5754
5755    @Override
5756    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5757        if (!(pendingResult instanceof PendingIntentRecord)) {
5758            return false;
5759        }
5760        try {
5761            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5762            if (res.key.allIntents == null) {
5763                return false;
5764            }
5765            for (int i=0; i<res.key.allIntents.length; i++) {
5766                Intent intent = res.key.allIntents[i];
5767                if (intent.getPackage() != null && intent.getComponent() != null) {
5768                    return false;
5769                }
5770            }
5771            return true;
5772        } catch (ClassCastException e) {
5773        }
5774        return false;
5775    }
5776
5777    @Override
5778    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5779        if (!(pendingResult instanceof PendingIntentRecord)) {
5780            return false;
5781        }
5782        try {
5783            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5784            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5785                return true;
5786            }
5787            return false;
5788        } catch (ClassCastException e) {
5789        }
5790        return false;
5791    }
5792
5793    @Override
5794    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5795        if (!(pendingResult instanceof PendingIntentRecord)) {
5796            return null;
5797        }
5798        try {
5799            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5800            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5801        } catch (ClassCastException e) {
5802        }
5803        return null;
5804    }
5805
5806    @Override
5807    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5808        if (!(pendingResult instanceof PendingIntentRecord)) {
5809            return null;
5810        }
5811        try {
5812            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5813            Intent intent = res.key.requestIntent;
5814            if (intent != null) {
5815                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5816                        || res.lastTagPrefix.equals(prefix))) {
5817                    return res.lastTag;
5818                }
5819                res.lastTagPrefix = prefix;
5820                StringBuilder sb = new StringBuilder(128);
5821                if (prefix != null) {
5822                    sb.append(prefix);
5823                }
5824                if (intent.getAction() != null) {
5825                    sb.append(intent.getAction());
5826                } else if (intent.getComponent() != null) {
5827                    intent.getComponent().appendShortString(sb);
5828                } else {
5829                    sb.append("?");
5830                }
5831                return res.lastTag = sb.toString();
5832            }
5833        } catch (ClassCastException e) {
5834        }
5835        return null;
5836    }
5837
5838    @Override
5839    public void setProcessLimit(int max) {
5840        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5841                "setProcessLimit()");
5842        synchronized (this) {
5843            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5844            mProcessLimitOverride = max;
5845        }
5846        trimApplications();
5847    }
5848
5849    @Override
5850    public int getProcessLimit() {
5851        synchronized (this) {
5852            return mProcessLimitOverride;
5853        }
5854    }
5855
5856    void foregroundTokenDied(ForegroundToken token) {
5857        synchronized (ActivityManagerService.this) {
5858            synchronized (mPidsSelfLocked) {
5859                ForegroundToken cur
5860                    = mForegroundProcesses.get(token.pid);
5861                if (cur != token) {
5862                    return;
5863                }
5864                mForegroundProcesses.remove(token.pid);
5865                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5866                if (pr == null) {
5867                    return;
5868                }
5869                pr.forcingToForeground = null;
5870                updateProcessForegroundLocked(pr, false, false);
5871            }
5872            updateOomAdjLocked();
5873        }
5874    }
5875
5876    @Override
5877    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5878        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5879                "setProcessForeground()");
5880        synchronized(this) {
5881            boolean changed = false;
5882
5883            synchronized (mPidsSelfLocked) {
5884                ProcessRecord pr = mPidsSelfLocked.get(pid);
5885                if (pr == null && isForeground) {
5886                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5887                    return;
5888                }
5889                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5890                if (oldToken != null) {
5891                    oldToken.token.unlinkToDeath(oldToken, 0);
5892                    mForegroundProcesses.remove(pid);
5893                    if (pr != null) {
5894                        pr.forcingToForeground = null;
5895                    }
5896                    changed = true;
5897                }
5898                if (isForeground && token != null) {
5899                    ForegroundToken newToken = new ForegroundToken() {
5900                        @Override
5901                        public void binderDied() {
5902                            foregroundTokenDied(this);
5903                        }
5904                    };
5905                    newToken.pid = pid;
5906                    newToken.token = token;
5907                    try {
5908                        token.linkToDeath(newToken, 0);
5909                        mForegroundProcesses.put(pid, newToken);
5910                        pr.forcingToForeground = token;
5911                        changed = true;
5912                    } catch (RemoteException e) {
5913                        // If the process died while doing this, we will later
5914                        // do the cleanup with the process death link.
5915                    }
5916                }
5917            }
5918
5919            if (changed) {
5920                updateOomAdjLocked();
5921            }
5922        }
5923    }
5924
5925    // =========================================================
5926    // PERMISSIONS
5927    // =========================================================
5928
5929    static class PermissionController extends IPermissionController.Stub {
5930        ActivityManagerService mActivityManagerService;
5931        PermissionController(ActivityManagerService activityManagerService) {
5932            mActivityManagerService = activityManagerService;
5933        }
5934
5935        @Override
5936        public boolean checkPermission(String permission, int pid, int uid) {
5937            return mActivityManagerService.checkPermission(permission, pid,
5938                    uid) == PackageManager.PERMISSION_GRANTED;
5939        }
5940    }
5941
5942    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5943        @Override
5944        public int checkComponentPermission(String permission, int pid, int uid,
5945                int owningUid, boolean exported) {
5946            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5947                    owningUid, exported);
5948        }
5949
5950        @Override
5951        public Object getAMSLock() {
5952            return ActivityManagerService.this;
5953        }
5954    }
5955
5956    /**
5957     * This can be called with or without the global lock held.
5958     */
5959    int checkComponentPermission(String permission, int pid, int uid,
5960            int owningUid, boolean exported) {
5961        // We might be performing an operation on behalf of an indirect binder
5962        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5963        // client identity accordingly before proceeding.
5964        Identity tlsIdentity = sCallerIdentity.get();
5965        if (tlsIdentity != null) {
5966            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5967                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5968            uid = tlsIdentity.uid;
5969            pid = tlsIdentity.pid;
5970        }
5971
5972        if (pid == MY_PID) {
5973            return PackageManager.PERMISSION_GRANTED;
5974        }
5975
5976        return ActivityManager.checkComponentPermission(permission, uid,
5977                owningUid, exported);
5978    }
5979
5980    /**
5981     * As the only public entry point for permissions checking, this method
5982     * can enforce the semantic that requesting a check on a null global
5983     * permission is automatically denied.  (Internally a null permission
5984     * string is used when calling {@link #checkComponentPermission} in cases
5985     * when only uid-based security is needed.)
5986     *
5987     * This can be called with or without the global lock held.
5988     */
5989    @Override
5990    public int checkPermission(String permission, int pid, int uid) {
5991        if (permission == null) {
5992            return PackageManager.PERMISSION_DENIED;
5993        }
5994        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5995    }
5996
5997    /**
5998     * Binder IPC calls go through the public entry point.
5999     * This can be called with or without the global lock held.
6000     */
6001    int checkCallingPermission(String permission) {
6002        return checkPermission(permission,
6003                Binder.getCallingPid(),
6004                UserHandle.getAppId(Binder.getCallingUid()));
6005    }
6006
6007    /**
6008     * This can be called with or without the global lock held.
6009     */
6010    void enforceCallingPermission(String permission, String func) {
6011        if (checkCallingPermission(permission)
6012                == PackageManager.PERMISSION_GRANTED) {
6013            return;
6014        }
6015
6016        String msg = "Permission Denial: " + func + " from pid="
6017                + Binder.getCallingPid()
6018                + ", uid=" + Binder.getCallingUid()
6019                + " requires " + permission;
6020        Slog.w(TAG, msg);
6021        throw new SecurityException(msg);
6022    }
6023
6024    /**
6025     * Determine if UID is holding permissions required to access {@link Uri} in
6026     * the given {@link ProviderInfo}. Final permission checking is always done
6027     * in {@link ContentProvider}.
6028     */
6029    private final boolean checkHoldingPermissionsLocked(
6030            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6031        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6032                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6033
6034        if (pi.applicationInfo.uid == uid) {
6035            return true;
6036        } else if (!pi.exported) {
6037            return false;
6038        }
6039
6040        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6041        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6042        try {
6043            // check if target holds top-level <provider> permissions
6044            if (!readMet && pi.readPermission != null
6045                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6046                readMet = true;
6047            }
6048            if (!writeMet && pi.writePermission != null
6049                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6050                writeMet = true;
6051            }
6052
6053            // track if unprotected read/write is allowed; any denied
6054            // <path-permission> below removes this ability
6055            boolean allowDefaultRead = pi.readPermission == null;
6056            boolean allowDefaultWrite = pi.writePermission == null;
6057
6058            // check if target holds any <path-permission> that match uri
6059            final PathPermission[] pps = pi.pathPermissions;
6060            if (pps != null) {
6061                final String path = grantUri.uri.getPath();
6062                int i = pps.length;
6063                while (i > 0 && (!readMet || !writeMet)) {
6064                    i--;
6065                    PathPermission pp = pps[i];
6066                    if (pp.match(path)) {
6067                        if (!readMet) {
6068                            final String pprperm = pp.getReadPermission();
6069                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6070                                    + pprperm + " for " + pp.getPath()
6071                                    + ": match=" + pp.match(path)
6072                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6073                            if (pprperm != null) {
6074                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6075                                    readMet = true;
6076                                } else {
6077                                    allowDefaultRead = false;
6078                                }
6079                            }
6080                        }
6081                        if (!writeMet) {
6082                            final String ppwperm = pp.getWritePermission();
6083                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6084                                    + ppwperm + " for " + pp.getPath()
6085                                    + ": match=" + pp.match(path)
6086                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6087                            if (ppwperm != null) {
6088                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6089                                    writeMet = true;
6090                                } else {
6091                                    allowDefaultWrite = false;
6092                                }
6093                            }
6094                        }
6095                    }
6096                }
6097            }
6098
6099            // grant unprotected <provider> read/write, if not blocked by
6100            // <path-permission> above
6101            if (allowDefaultRead) readMet = true;
6102            if (allowDefaultWrite) writeMet = true;
6103
6104        } catch (RemoteException e) {
6105            return false;
6106        }
6107
6108        return readMet && writeMet;
6109    }
6110
6111    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6112        ProviderInfo pi = null;
6113        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6114        if (cpr != null) {
6115            pi = cpr.info;
6116        } else {
6117            try {
6118                pi = AppGlobals.getPackageManager().resolveContentProvider(
6119                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6120            } catch (RemoteException ex) {
6121            }
6122        }
6123        return pi;
6124    }
6125
6126    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6127        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6128        if (targetUris != null) {
6129            return targetUris.get(grantUri);
6130        }
6131        return null;
6132    }
6133
6134    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6135            String targetPkg, int targetUid, GrantUri grantUri) {
6136        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6137        if (targetUris == null) {
6138            targetUris = Maps.newArrayMap();
6139            mGrantedUriPermissions.put(targetUid, targetUris);
6140        }
6141
6142        UriPermission perm = targetUris.get(grantUri);
6143        if (perm == null) {
6144            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6145            targetUris.put(grantUri, perm);
6146        }
6147
6148        return perm;
6149    }
6150
6151    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6152            final int modeFlags) {
6153        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6154        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6155                : UriPermission.STRENGTH_OWNED;
6156
6157        // Root gets to do everything.
6158        if (uid == 0) {
6159            return true;
6160        }
6161
6162        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6163        if (perms == null) return false;
6164
6165        // First look for exact match
6166        final UriPermission exactPerm = perms.get(grantUri);
6167        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6168            return true;
6169        }
6170
6171        // No exact match, look for prefixes
6172        final int N = perms.size();
6173        for (int i = 0; i < N; i++) {
6174            final UriPermission perm = perms.valueAt(i);
6175            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6176                    && perm.getStrength(modeFlags) >= minStrength) {
6177                return true;
6178            }
6179        }
6180
6181        return false;
6182    }
6183
6184    @Override
6185    public int checkUriPermission(Uri uri, int pid, int uid,
6186            final int modeFlags, int userId) {
6187        enforceNotIsolatedCaller("checkUriPermission");
6188
6189        // Another redirected-binder-call permissions check as in
6190        // {@link checkComponentPermission}.
6191        Identity tlsIdentity = sCallerIdentity.get();
6192        if (tlsIdentity != null) {
6193            uid = tlsIdentity.uid;
6194            pid = tlsIdentity.pid;
6195        }
6196
6197        // Our own process gets to do everything.
6198        if (pid == MY_PID) {
6199            return PackageManager.PERMISSION_GRANTED;
6200        }
6201        synchronized (this) {
6202            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6203                    ? PackageManager.PERMISSION_GRANTED
6204                    : PackageManager.PERMISSION_DENIED;
6205        }
6206    }
6207
6208    /**
6209     * Check if the targetPkg can be granted permission to access uri by
6210     * the callingUid using the given modeFlags.  Throws a security exception
6211     * if callingUid is not allowed to do this.  Returns the uid of the target
6212     * if the URI permission grant should be performed; returns -1 if it is not
6213     * needed (for example targetPkg already has permission to access the URI).
6214     * If you already know the uid of the target, you can supply it in
6215     * lastTargetUid else set that to -1.
6216     */
6217    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6218            final int modeFlags, int lastTargetUid) {
6219        if (!Intent.isAccessUriMode(modeFlags)) {
6220            return -1;
6221        }
6222
6223        if (targetPkg != null) {
6224            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6225                    "Checking grant " + targetPkg + " permission to " + grantUri);
6226        }
6227
6228        final IPackageManager pm = AppGlobals.getPackageManager();
6229
6230        // If this is not a content: uri, we can't do anything with it.
6231        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6232            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6233                    "Can't grant URI permission for non-content URI: " + grantUri);
6234            return -1;
6235        }
6236
6237        final String authority = grantUri.uri.getAuthority();
6238        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6239        if (pi == null) {
6240            Slog.w(TAG, "No content provider found for permission check: " +
6241                    grantUri.uri.toSafeString());
6242            return -1;
6243        }
6244
6245        int targetUid = lastTargetUid;
6246        if (targetUid < 0 && targetPkg != null) {
6247            try {
6248                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6249                if (targetUid < 0) {
6250                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6251                            "Can't grant URI permission no uid for: " + targetPkg);
6252                    return -1;
6253                }
6254            } catch (RemoteException ex) {
6255                return -1;
6256            }
6257        }
6258
6259        if (targetUid >= 0) {
6260            // First...  does the target actually need this permission?
6261            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6262                // No need to grant the target this permission.
6263                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6264                        "Target " + targetPkg + " already has full permission to " + grantUri);
6265                return -1;
6266            }
6267        } else {
6268            // First...  there is no target package, so can anyone access it?
6269            boolean allowed = pi.exported;
6270            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6271                if (pi.readPermission != null) {
6272                    allowed = false;
6273                }
6274            }
6275            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6276                if (pi.writePermission != null) {
6277                    allowed = false;
6278                }
6279            }
6280            if (allowed) {
6281                return -1;
6282            }
6283        }
6284
6285        // Second...  is the provider allowing granting of URI permissions?
6286        if (!pi.grantUriPermissions) {
6287            throw new SecurityException("Provider " + pi.packageName
6288                    + "/" + pi.name
6289                    + " does not allow granting of Uri permissions (uri "
6290                    + grantUri + ")");
6291        }
6292        if (pi.uriPermissionPatterns != null) {
6293            final int N = pi.uriPermissionPatterns.length;
6294            boolean allowed = false;
6295            for (int i=0; i<N; i++) {
6296                if (pi.uriPermissionPatterns[i] != null
6297                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6298                    allowed = true;
6299                    break;
6300                }
6301            }
6302            if (!allowed) {
6303                throw new SecurityException("Provider " + pi.packageName
6304                        + "/" + pi.name
6305                        + " does not allow granting of permission to path of Uri "
6306                        + grantUri);
6307            }
6308        }
6309
6310        // Third...  does the caller itself have permission to access
6311        // this uri?
6312        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6313            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6314                // Require they hold a strong enough Uri permission
6315                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6316                    throw new SecurityException("Uid " + callingUid
6317                            + " does not have permission to uri " + grantUri);
6318                }
6319            }
6320        }
6321        return targetUid;
6322    }
6323
6324    @Override
6325    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6326            final int modeFlags, int userId) {
6327        enforceNotIsolatedCaller("checkGrantUriPermission");
6328        synchronized(this) {
6329            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6330                    new GrantUri(userId, uri, false), modeFlags, -1);
6331        }
6332    }
6333
6334    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6335            final int modeFlags, UriPermissionOwner owner) {
6336        if (!Intent.isAccessUriMode(modeFlags)) {
6337            return;
6338        }
6339
6340        // So here we are: the caller has the assumed permission
6341        // to the uri, and the target doesn't.  Let's now give this to
6342        // the target.
6343
6344        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6345                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6346
6347        final String authority = grantUri.uri.getAuthority();
6348        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6349        if (pi == null) {
6350            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6351            return;
6352        }
6353
6354        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6355            grantUri.prefix = true;
6356        }
6357        final UriPermission perm = findOrCreateUriPermissionLocked(
6358                pi.packageName, targetPkg, targetUid, grantUri);
6359        perm.grantModes(modeFlags, owner);
6360    }
6361
6362    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6363            final int modeFlags, UriPermissionOwner owner) {
6364        if (targetPkg == null) {
6365            throw new NullPointerException("targetPkg");
6366        }
6367
6368        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6369                -1);
6370        if (targetUid < 0) {
6371            return;
6372        }
6373
6374        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6375                owner);
6376    }
6377
6378    static class NeededUriGrants extends ArrayList<GrantUri> {
6379        final String targetPkg;
6380        final int targetUid;
6381        final int flags;
6382
6383        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6384            this.targetPkg = targetPkg;
6385            this.targetUid = targetUid;
6386            this.flags = flags;
6387        }
6388    }
6389
6390    /**
6391     * Like checkGrantUriPermissionLocked, but takes an Intent.
6392     */
6393    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6394            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6395        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6396                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6397                + " clip=" + (intent != null ? intent.getClipData() : null)
6398                + " from " + intent + "; flags=0x"
6399                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6400
6401        if (targetPkg == null) {
6402            throw new NullPointerException("targetPkg");
6403        }
6404
6405        if (intent == null) {
6406            return null;
6407        }
6408        Uri data = intent.getData();
6409        ClipData clip = intent.getClipData();
6410        if (data == null && clip == null) {
6411            return null;
6412        }
6413
6414        if (data != null) {
6415            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6416            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6417                    needed != null ? needed.targetUid : -1);
6418            if (targetUid > 0) {
6419                if (needed == null) {
6420                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6421                }
6422                needed.add(grantUri);
6423            }
6424        }
6425        if (clip != null) {
6426            for (int i=0; i<clip.getItemCount(); i++) {
6427                Uri uri = clip.getItemAt(i).getUri();
6428                if (uri != null) {
6429                    int targetUid = -1;
6430                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6431                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6432                            needed != null ? needed.targetUid : -1);
6433                    if (targetUid > 0) {
6434                        if (needed == null) {
6435                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6436                        }
6437                        needed.add(grantUri);
6438                    }
6439                } else {
6440                    Intent clipIntent = clip.getItemAt(i).getIntent();
6441                    if (clipIntent != null) {
6442                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6443                                callingUid, targetPkg, clipIntent, mode, needed);
6444                        if (newNeeded != null) {
6445                            needed = newNeeded;
6446                        }
6447                    }
6448                }
6449            }
6450        }
6451
6452        return needed;
6453    }
6454
6455    /**
6456     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6457     */
6458    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6459            UriPermissionOwner owner) {
6460        if (needed != null) {
6461            for (int i=0; i<needed.size(); i++) {
6462                GrantUri grantUri = needed.get(i);
6463                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6464                        grantUri, needed.flags, owner);
6465            }
6466        }
6467    }
6468
6469    void grantUriPermissionFromIntentLocked(int callingUid,
6470            String targetPkg, Intent intent, UriPermissionOwner owner) {
6471        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6472                intent, intent != null ? intent.getFlags() : 0, null);
6473        if (needed == null) {
6474            return;
6475        }
6476
6477        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6478    }
6479
6480    @Override
6481    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6482            final int modeFlags, int userId) {
6483        enforceNotIsolatedCaller("grantUriPermission");
6484        GrantUri grantUri = new GrantUri(userId, uri, false);
6485        synchronized(this) {
6486            final ProcessRecord r = getRecordForAppLocked(caller);
6487            if (r == null) {
6488                throw new SecurityException("Unable to find app for caller "
6489                        + caller
6490                        + " when granting permission to uri " + grantUri);
6491            }
6492            if (targetPkg == null) {
6493                throw new IllegalArgumentException("null target");
6494            }
6495            if (grantUri == null) {
6496                throw new IllegalArgumentException("null uri");
6497            }
6498
6499            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6500                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6501                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6502                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6503
6504            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6505        }
6506    }
6507
6508    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6509        if (perm.modeFlags == 0) {
6510            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6511                    perm.targetUid);
6512            if (perms != null) {
6513                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6514                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6515
6516                perms.remove(perm.uri);
6517                if (perms.isEmpty()) {
6518                    mGrantedUriPermissions.remove(perm.targetUid);
6519                }
6520            }
6521        }
6522    }
6523
6524    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6525        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6526
6527        final IPackageManager pm = AppGlobals.getPackageManager();
6528        final String authority = grantUri.uri.getAuthority();
6529        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6530        if (pi == null) {
6531            Slog.w(TAG, "No content provider found for permission revoke: "
6532                    + grantUri.toSafeString());
6533            return;
6534        }
6535
6536        // Does the caller have this permission on the URI?
6537        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6538            // Right now, if you are not the original owner of the permission,
6539            // you are not allowed to revoke it.
6540            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6541                throw new SecurityException("Uid " + callingUid
6542                        + " does not have permission to uri " + grantUri);
6543            //}
6544        }
6545
6546        boolean persistChanged = false;
6547
6548        // Go through all of the permissions and remove any that match.
6549        int N = mGrantedUriPermissions.size();
6550        for (int i = 0; i < N; i++) {
6551            final int targetUid = mGrantedUriPermissions.keyAt(i);
6552            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6553
6554            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6555                final UriPermission perm = it.next();
6556                if (perm.uri.sourceUserId == grantUri.sourceUserId
6557                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6558                    if (DEBUG_URI_PERMISSION)
6559                        Slog.v(TAG,
6560                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6561                    persistChanged |= perm.revokeModes(
6562                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6563                    if (perm.modeFlags == 0) {
6564                        it.remove();
6565                    }
6566                }
6567            }
6568
6569            if (perms.isEmpty()) {
6570                mGrantedUriPermissions.remove(targetUid);
6571                N--;
6572                i--;
6573            }
6574        }
6575
6576        if (persistChanged) {
6577            schedulePersistUriGrants();
6578        }
6579    }
6580
6581    @Override
6582    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6583            int userId) {
6584        enforceNotIsolatedCaller("revokeUriPermission");
6585        synchronized(this) {
6586            final ProcessRecord r = getRecordForAppLocked(caller);
6587            if (r == null) {
6588                throw new SecurityException("Unable to find app for caller "
6589                        + caller
6590                        + " when revoking permission to uri " + uri);
6591            }
6592            if (uri == null) {
6593                Slog.w(TAG, "revokeUriPermission: null uri");
6594                return;
6595            }
6596
6597            if (!Intent.isAccessUriMode(modeFlags)) {
6598                return;
6599            }
6600
6601            final IPackageManager pm = AppGlobals.getPackageManager();
6602            final String authority = uri.getAuthority();
6603            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6604            if (pi == null) {
6605                Slog.w(TAG, "No content provider found for permission revoke: "
6606                        + uri.toSafeString());
6607                return;
6608            }
6609
6610            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6611        }
6612    }
6613
6614    /**
6615     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6616     * given package.
6617     *
6618     * @param packageName Package name to match, or {@code null} to apply to all
6619     *            packages.
6620     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6621     *            to all users.
6622     * @param persistable If persistable grants should be removed.
6623     */
6624    private void removeUriPermissionsForPackageLocked(
6625            String packageName, int userHandle, boolean persistable) {
6626        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6627            throw new IllegalArgumentException("Must narrow by either package or user");
6628        }
6629
6630        boolean persistChanged = false;
6631
6632        int N = mGrantedUriPermissions.size();
6633        for (int i = 0; i < N; i++) {
6634            final int targetUid = mGrantedUriPermissions.keyAt(i);
6635            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6636
6637            // Only inspect grants matching user
6638            if (userHandle == UserHandle.USER_ALL
6639                    || userHandle == UserHandle.getUserId(targetUid)) {
6640                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6641                    final UriPermission perm = it.next();
6642
6643                    // Only inspect grants matching package
6644                    if (packageName == null || perm.sourcePkg.equals(packageName)
6645                            || perm.targetPkg.equals(packageName)) {
6646                        persistChanged |= perm.revokeModes(
6647                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6648
6649                        // Only remove when no modes remain; any persisted grants
6650                        // will keep this alive.
6651                        if (perm.modeFlags == 0) {
6652                            it.remove();
6653                        }
6654                    }
6655                }
6656
6657                if (perms.isEmpty()) {
6658                    mGrantedUriPermissions.remove(targetUid);
6659                    N--;
6660                    i--;
6661                }
6662            }
6663        }
6664
6665        if (persistChanged) {
6666            schedulePersistUriGrants();
6667        }
6668    }
6669
6670    @Override
6671    public IBinder newUriPermissionOwner(String name) {
6672        enforceNotIsolatedCaller("newUriPermissionOwner");
6673        synchronized(this) {
6674            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6675            return owner.getExternalTokenLocked();
6676        }
6677    }
6678
6679    @Override
6680    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6681            final int modeFlags, int userId) {
6682        synchronized(this) {
6683            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6684            if (owner == null) {
6685                throw new IllegalArgumentException("Unknown owner: " + token);
6686            }
6687            if (fromUid != Binder.getCallingUid()) {
6688                if (Binder.getCallingUid() != Process.myUid()) {
6689                    // Only system code can grant URI permissions on behalf
6690                    // of other users.
6691                    throw new SecurityException("nice try");
6692                }
6693            }
6694            if (targetPkg == null) {
6695                throw new IllegalArgumentException("null target");
6696            }
6697            if (uri == null) {
6698                throw new IllegalArgumentException("null uri");
6699            }
6700
6701            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6702                    modeFlags, owner);
6703        }
6704    }
6705
6706    @Override
6707    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6708        synchronized(this) {
6709            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6710            if (owner == null) {
6711                throw new IllegalArgumentException("Unknown owner: " + token);
6712            }
6713
6714            if (uri == null) {
6715                owner.removeUriPermissionsLocked(mode);
6716            } else {
6717                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6718            }
6719        }
6720    }
6721
6722    private void schedulePersistUriGrants() {
6723        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6724            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6725                    10 * DateUtils.SECOND_IN_MILLIS);
6726        }
6727    }
6728
6729    private void writeGrantedUriPermissions() {
6730        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6731
6732        // Snapshot permissions so we can persist without lock
6733        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6734        synchronized (this) {
6735            final int size = mGrantedUriPermissions.size();
6736            for (int i = 0; i < size; i++) {
6737                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6738                for (UriPermission perm : perms.values()) {
6739                    if (perm.persistedModeFlags != 0) {
6740                        persist.add(perm.snapshot());
6741                    }
6742                }
6743            }
6744        }
6745
6746        FileOutputStream fos = null;
6747        try {
6748            fos = mGrantFile.startWrite();
6749
6750            XmlSerializer out = new FastXmlSerializer();
6751            out.setOutput(fos, "utf-8");
6752            out.startDocument(null, true);
6753            out.startTag(null, TAG_URI_GRANTS);
6754            for (UriPermission.Snapshot perm : persist) {
6755                out.startTag(null, TAG_URI_GRANT);
6756                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6757                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6758                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6759                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6760                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6761                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6762                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6763                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6764                out.endTag(null, TAG_URI_GRANT);
6765            }
6766            out.endTag(null, TAG_URI_GRANTS);
6767            out.endDocument();
6768
6769            mGrantFile.finishWrite(fos);
6770        } catch (IOException e) {
6771            if (fos != null) {
6772                mGrantFile.failWrite(fos);
6773            }
6774        }
6775    }
6776
6777    private void readGrantedUriPermissionsLocked() {
6778        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6779
6780        final long now = System.currentTimeMillis();
6781
6782        FileInputStream fis = null;
6783        try {
6784            fis = mGrantFile.openRead();
6785            final XmlPullParser in = Xml.newPullParser();
6786            in.setInput(fis, null);
6787
6788            int type;
6789            while ((type = in.next()) != END_DOCUMENT) {
6790                final String tag = in.getName();
6791                if (type == START_TAG) {
6792                    if (TAG_URI_GRANT.equals(tag)) {
6793                        final int sourceUserId;
6794                        final int targetUserId;
6795                        final int userHandle = readIntAttribute(in,
6796                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6797                        if (userHandle != UserHandle.USER_NULL) {
6798                            // For backwards compatibility.
6799                            sourceUserId = userHandle;
6800                            targetUserId = userHandle;
6801                        } else {
6802                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6803                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6804                        }
6805                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6806                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6807                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6808                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6809                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6810                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6811
6812                        // Sanity check that provider still belongs to source package
6813                        final ProviderInfo pi = getProviderInfoLocked(
6814                                uri.getAuthority(), sourceUserId);
6815                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6816                            int targetUid = -1;
6817                            try {
6818                                targetUid = AppGlobals.getPackageManager()
6819                                        .getPackageUid(targetPkg, targetUserId);
6820                            } catch (RemoteException e) {
6821                            }
6822                            if (targetUid != -1) {
6823                                final UriPermission perm = findOrCreateUriPermissionLocked(
6824                                        sourcePkg, targetPkg, targetUid,
6825                                        new GrantUri(sourceUserId, uri, prefix));
6826                                perm.initPersistedModes(modeFlags, createdTime);
6827                            }
6828                        } else {
6829                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6830                                    + " but instead found " + pi);
6831                        }
6832                    }
6833                }
6834            }
6835        } catch (FileNotFoundException e) {
6836            // Missing grants is okay
6837        } catch (IOException e) {
6838            Log.wtf(TAG, "Failed reading Uri grants", e);
6839        } catch (XmlPullParserException e) {
6840            Log.wtf(TAG, "Failed reading Uri grants", e);
6841        } finally {
6842            IoUtils.closeQuietly(fis);
6843        }
6844    }
6845
6846    @Override
6847    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6848        enforceNotIsolatedCaller("takePersistableUriPermission");
6849
6850        Preconditions.checkFlagsArgument(modeFlags,
6851                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6852
6853        synchronized (this) {
6854            final int callingUid = Binder.getCallingUid();
6855            boolean persistChanged = false;
6856            GrantUri grantUri = new GrantUri(userId, uri, false);
6857
6858            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6859                    new GrantUri(userId, uri, false));
6860            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6861                    new GrantUri(userId, uri, true));
6862
6863            final boolean exactValid = (exactPerm != null)
6864                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6865            final boolean prefixValid = (prefixPerm != null)
6866                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6867
6868            if (!(exactValid || prefixValid)) {
6869                throw new SecurityException("No persistable permission grants found for UID "
6870                        + callingUid + " and Uri " + grantUri.toSafeString());
6871            }
6872
6873            if (exactValid) {
6874                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6875            }
6876            if (prefixValid) {
6877                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6878            }
6879
6880            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6881
6882            if (persistChanged) {
6883                schedulePersistUriGrants();
6884            }
6885        }
6886    }
6887
6888    @Override
6889    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6890        enforceNotIsolatedCaller("releasePersistableUriPermission");
6891
6892        Preconditions.checkFlagsArgument(modeFlags,
6893                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6894
6895        synchronized (this) {
6896            final int callingUid = Binder.getCallingUid();
6897            boolean persistChanged = false;
6898
6899            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6900                    new GrantUri(userId, uri, false));
6901            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6902                    new GrantUri(userId, uri, true));
6903            if (exactPerm == null && prefixPerm == null) {
6904                throw new SecurityException("No permission grants found for UID " + callingUid
6905                        + " and Uri " + uri.toSafeString());
6906            }
6907
6908            if (exactPerm != null) {
6909                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6910                removeUriPermissionIfNeededLocked(exactPerm);
6911            }
6912            if (prefixPerm != null) {
6913                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6914                removeUriPermissionIfNeededLocked(prefixPerm);
6915            }
6916
6917            if (persistChanged) {
6918                schedulePersistUriGrants();
6919            }
6920        }
6921    }
6922
6923    /**
6924     * Prune any older {@link UriPermission} for the given UID until outstanding
6925     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6926     *
6927     * @return if any mutations occured that require persisting.
6928     */
6929    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6930        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6931        if (perms == null) return false;
6932        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6933
6934        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6935        for (UriPermission perm : perms.values()) {
6936            if (perm.persistedModeFlags != 0) {
6937                persisted.add(perm);
6938            }
6939        }
6940
6941        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6942        if (trimCount <= 0) return false;
6943
6944        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6945        for (int i = 0; i < trimCount; i++) {
6946            final UriPermission perm = persisted.get(i);
6947
6948            if (DEBUG_URI_PERMISSION) {
6949                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6950            }
6951
6952            perm.releasePersistableModes(~0);
6953            removeUriPermissionIfNeededLocked(perm);
6954        }
6955
6956        return true;
6957    }
6958
6959    @Override
6960    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6961            String packageName, boolean incoming) {
6962        enforceNotIsolatedCaller("getPersistedUriPermissions");
6963        Preconditions.checkNotNull(packageName, "packageName");
6964
6965        final int callingUid = Binder.getCallingUid();
6966        final IPackageManager pm = AppGlobals.getPackageManager();
6967        try {
6968            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6969            if (packageUid != callingUid) {
6970                throw new SecurityException(
6971                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6972            }
6973        } catch (RemoteException e) {
6974            throw new SecurityException("Failed to verify package name ownership");
6975        }
6976
6977        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6978        synchronized (this) {
6979            if (incoming) {
6980                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6981                        callingUid);
6982                if (perms == null) {
6983                    Slog.w(TAG, "No permission grants found for " + packageName);
6984                } else {
6985                    for (UriPermission perm : perms.values()) {
6986                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6987                            result.add(perm.buildPersistedPublicApiObject());
6988                        }
6989                    }
6990                }
6991            } else {
6992                final int size = mGrantedUriPermissions.size();
6993                for (int i = 0; i < size; i++) {
6994                    final ArrayMap<GrantUri, UriPermission> perms =
6995                            mGrantedUriPermissions.valueAt(i);
6996                    for (UriPermission perm : perms.values()) {
6997                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6998                            result.add(perm.buildPersistedPublicApiObject());
6999                        }
7000                    }
7001                }
7002            }
7003        }
7004        return new ParceledListSlice<android.content.UriPermission>(result);
7005    }
7006
7007    @Override
7008    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7009        synchronized (this) {
7010            ProcessRecord app =
7011                who != null ? getRecordForAppLocked(who) : null;
7012            if (app == null) return;
7013
7014            Message msg = Message.obtain();
7015            msg.what = WAIT_FOR_DEBUGGER_MSG;
7016            msg.obj = app;
7017            msg.arg1 = waiting ? 1 : 0;
7018            mHandler.sendMessage(msg);
7019        }
7020    }
7021
7022    @Override
7023    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7024        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7025        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7026        outInfo.availMem = Process.getFreeMemory();
7027        outInfo.totalMem = Process.getTotalMemory();
7028        outInfo.threshold = homeAppMem;
7029        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7030        outInfo.hiddenAppThreshold = cachedAppMem;
7031        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7032                ProcessList.SERVICE_ADJ);
7033        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7034                ProcessList.VISIBLE_APP_ADJ);
7035        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7036                ProcessList.FOREGROUND_APP_ADJ);
7037    }
7038
7039    // =========================================================
7040    // TASK MANAGEMENT
7041    // =========================================================
7042
7043    @Override
7044    public List<IAppTask> getAppTasks() {
7045        int callingUid = Binder.getCallingUid();
7046        long ident = Binder.clearCallingIdentity();
7047        synchronized(this) {
7048            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7049            try {
7050                if (localLOGV) Slog.v(TAG, "getAppTasks");
7051
7052                final int N = mRecentTasks.size();
7053                for (int i = 0; i < N; i++) {
7054                    TaskRecord tr = mRecentTasks.get(i);
7055                    // Skip tasks that are not created by the caller
7056                    if (tr.creatorUid == callingUid) {
7057                        ActivityManager.RecentTaskInfo taskInfo =
7058                                createRecentTaskInfoFromTaskRecord(tr);
7059                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7060                        list.add(taskImpl);
7061                    }
7062                }
7063            } finally {
7064                Binder.restoreCallingIdentity(ident);
7065            }
7066            return list;
7067        }
7068    }
7069
7070    @Override
7071    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7072        final int callingUid = Binder.getCallingUid();
7073        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7074
7075        synchronized(this) {
7076            if (localLOGV) Slog.v(
7077                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7078
7079            final boolean allowed = checkCallingPermission(
7080                    android.Manifest.permission.GET_TASKS)
7081                    == PackageManager.PERMISSION_GRANTED;
7082            if (!allowed) {
7083                Slog.w(TAG, "getTasks: caller " + callingUid
7084                        + " does not hold GET_TASKS; limiting output");
7085            }
7086
7087            // TODO: Improve with MRU list from all ActivityStacks.
7088            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7089        }
7090
7091        return list;
7092    }
7093
7094    TaskRecord getMostRecentTask() {
7095        return mRecentTasks.get(0);
7096    }
7097
7098    /**
7099     * Creates a new RecentTaskInfo from a TaskRecord.
7100     */
7101    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7102        // Update the task description to reflect any changes in the task stack
7103        tr.updateTaskDescription();
7104
7105        // Compose the recent task info
7106        ActivityManager.RecentTaskInfo rti
7107                = new ActivityManager.RecentTaskInfo();
7108        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7109        rti.persistentId = tr.taskId;
7110        rti.baseIntent = new Intent(tr.getBaseIntent());
7111        rti.origActivity = tr.origActivity;
7112        rti.description = tr.lastDescription;
7113        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7114        rti.userId = tr.userId;
7115        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7116        return rti;
7117    }
7118
7119    @Override
7120    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7121            int flags, int userId) {
7122        final int callingUid = Binder.getCallingUid();
7123        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7124                false, true, "getRecentTasks", null);
7125
7126        synchronized (this) {
7127            final boolean allowed = checkCallingPermission(
7128                    android.Manifest.permission.GET_TASKS)
7129                    == PackageManager.PERMISSION_GRANTED;
7130            if (!allowed) {
7131                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7132                        + " does not hold GET_TASKS; limiting output");
7133            }
7134            final boolean detailed = checkCallingPermission(
7135                    android.Manifest.permission.GET_DETAILED_TASKS)
7136                    == PackageManager.PERMISSION_GRANTED;
7137
7138            IPackageManager pm = AppGlobals.getPackageManager();
7139
7140            final int N = mRecentTasks.size();
7141            ArrayList<ActivityManager.RecentTaskInfo> res
7142                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7143                            maxNum < N ? maxNum : N);
7144
7145            final Set<Integer> includedUsers;
7146            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7147                includedUsers = getProfileIdsLocked(userId);
7148            } else {
7149                includedUsers = new HashSet<Integer>();
7150            }
7151            includedUsers.add(Integer.valueOf(userId));
7152            for (int i=0; i<N && maxNum > 0; i++) {
7153                TaskRecord tr = mRecentTasks.get(i);
7154                // Only add calling user or related users recent tasks
7155                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7156
7157                // Return the entry if desired by the caller.  We always return
7158                // the first entry, because callers always expect this to be the
7159                // foreground app.  We may filter others if the caller has
7160                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7161                // we should exclude the entry.
7162
7163                if (i == 0
7164                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7165                        || (tr.intent == null)
7166                        || ((tr.intent.getFlags()
7167                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7168                    if (!allowed) {
7169                        // If the caller doesn't have the GET_TASKS permission, then only
7170                        // allow them to see a small subset of tasks -- their own and home.
7171                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7172                            continue;
7173                        }
7174                    }
7175
7176                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7177                    if (!detailed) {
7178                        rti.baseIntent.replaceExtras((Bundle)null);
7179                    }
7180
7181                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7182                        // Check whether this activity is currently available.
7183                        try {
7184                            if (rti.origActivity != null) {
7185                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7186                                        == null) {
7187                                    continue;
7188                                }
7189                            } else if (rti.baseIntent != null) {
7190                                if (pm.queryIntentActivities(rti.baseIntent,
7191                                        null, 0, userId) == null) {
7192                                    continue;
7193                                }
7194                            }
7195                        } catch (RemoteException e) {
7196                            // Will never happen.
7197                        }
7198                    }
7199
7200                    res.add(rti);
7201                    maxNum--;
7202                }
7203            }
7204            return res;
7205        }
7206    }
7207
7208    private TaskRecord recentTaskForIdLocked(int id) {
7209        final int N = mRecentTasks.size();
7210            for (int i=0; i<N; i++) {
7211                TaskRecord tr = mRecentTasks.get(i);
7212                if (tr.taskId == id) {
7213                    return tr;
7214                }
7215            }
7216            return null;
7217    }
7218
7219    @Override
7220    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7221        synchronized (this) {
7222            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7223                    "getTaskThumbnails()");
7224            TaskRecord tr = recentTaskForIdLocked(id);
7225            if (tr != null) {
7226                return tr.getTaskThumbnailsLocked();
7227            }
7228        }
7229        return null;
7230    }
7231
7232    @Override
7233    public Bitmap getTaskTopThumbnail(int id) {
7234        synchronized (this) {
7235            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7236                    "getTaskTopThumbnail()");
7237            TaskRecord tr = recentTaskForIdLocked(id);
7238            if (tr != null) {
7239                return tr.getTaskTopThumbnailLocked();
7240            }
7241        }
7242        return null;
7243    }
7244
7245    @Override
7246    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7247        synchronized (this) {
7248            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7249            if (r != null) {
7250                r.taskDescription = td;
7251                r.task.updateTaskDescription();
7252            }
7253        }
7254    }
7255
7256    @Override
7257    public boolean removeSubTask(int taskId, int subTaskIndex) {
7258        synchronized (this) {
7259            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7260                    "removeSubTask()");
7261            long ident = Binder.clearCallingIdentity();
7262            try {
7263                TaskRecord tr = recentTaskForIdLocked(taskId);
7264                if (tr != null) {
7265                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7266                }
7267                return false;
7268            } finally {
7269                Binder.restoreCallingIdentity(ident);
7270            }
7271        }
7272    }
7273
7274    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7275        if (!pr.killedByAm) {
7276            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7277            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7278                    pr.processName, pr.setAdj, reason);
7279            pr.killedByAm = true;
7280            Process.killProcessQuiet(pr.pid);
7281        }
7282    }
7283
7284    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7285        tr.disposeThumbnail();
7286        mRecentTasks.remove(tr);
7287        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7288        Intent baseIntent = new Intent(
7289                tr.intent != null ? tr.intent : tr.affinityIntent);
7290        ComponentName component = baseIntent.getComponent();
7291        if (component == null) {
7292            Slog.w(TAG, "Now component for base intent of task: " + tr);
7293            return;
7294        }
7295
7296        // Find any running services associated with this app.
7297        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7298
7299        if (killProcesses) {
7300            // Find any running processes associated with this app.
7301            final String pkg = component.getPackageName();
7302            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7303            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7304            for (int i=0; i<pmap.size(); i++) {
7305                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7306                for (int j=0; j<uids.size(); j++) {
7307                    ProcessRecord proc = uids.valueAt(j);
7308                    if (proc.userId != tr.userId) {
7309                        continue;
7310                    }
7311                    if (!proc.pkgList.containsKey(pkg)) {
7312                        continue;
7313                    }
7314                    procs.add(proc);
7315                }
7316            }
7317
7318            // Kill the running processes.
7319            for (int i=0; i<procs.size(); i++) {
7320                ProcessRecord pr = procs.get(i);
7321                if (pr == mHomeProcess) {
7322                    // Don't kill the home process along with tasks from the same package.
7323                    continue;
7324                }
7325                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7326                    killUnneededProcessLocked(pr, "remove task");
7327                } else {
7328                    pr.waitingToKill = "remove task";
7329                }
7330            }
7331        }
7332    }
7333
7334    /**
7335     * Removes the task with the specified task id.
7336     *
7337     * @param taskId Identifier of the task to be removed.
7338     * @param flags Additional operational flags.  May be 0 or
7339     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7340     * @return Returns true if the given task was found and removed.
7341     */
7342    private boolean removeTaskByIdLocked(int taskId, int flags) {
7343        TaskRecord tr = recentTaskForIdLocked(taskId);
7344        if (tr != null) {
7345            tr.removeTaskActivitiesLocked(-1, false);
7346            cleanUpRemovedTaskLocked(tr, flags);
7347            if (tr.isPersistable) {
7348                notifyTaskPersisterLocked(tr, true);
7349            }
7350            return true;
7351        }
7352        return false;
7353    }
7354
7355    @Override
7356    public boolean removeTask(int taskId, int flags) {
7357        synchronized (this) {
7358            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7359                    "removeTask()");
7360            long ident = Binder.clearCallingIdentity();
7361            try {
7362                return removeTaskByIdLocked(taskId, flags);
7363            } finally {
7364                Binder.restoreCallingIdentity(ident);
7365            }
7366        }
7367    }
7368
7369    /**
7370     * TODO: Add mController hook
7371     */
7372    @Override
7373    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7374        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7375                "moveTaskToFront()");
7376
7377        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7378        synchronized(this) {
7379            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7380                    Binder.getCallingUid(), "Task to front")) {
7381                ActivityOptions.abort(options);
7382                return;
7383            }
7384            final long origId = Binder.clearCallingIdentity();
7385            try {
7386                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7387                if (task == null) {
7388                    return;
7389                }
7390                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7391                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7392                    return;
7393                }
7394                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7395            } finally {
7396                Binder.restoreCallingIdentity(origId);
7397            }
7398            ActivityOptions.abort(options);
7399        }
7400    }
7401
7402    @Override
7403    public void moveTaskToBack(int taskId) {
7404        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7405                "moveTaskToBack()");
7406
7407        synchronized(this) {
7408            TaskRecord tr = recentTaskForIdLocked(taskId);
7409            if (tr != null) {
7410                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7411                ActivityStack stack = tr.stack;
7412                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7413                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7414                            Binder.getCallingUid(), "Task to back")) {
7415                        return;
7416                    }
7417                }
7418                final long origId = Binder.clearCallingIdentity();
7419                try {
7420                    stack.moveTaskToBackLocked(taskId, null);
7421                } finally {
7422                    Binder.restoreCallingIdentity(origId);
7423                }
7424            }
7425        }
7426    }
7427
7428    /**
7429     * Moves an activity, and all of the other activities within the same task, to the bottom
7430     * of the history stack.  The activity's order within the task is unchanged.
7431     *
7432     * @param token A reference to the activity we wish to move
7433     * @param nonRoot If false then this only works if the activity is the root
7434     *                of a task; if true it will work for any activity in a task.
7435     * @return Returns true if the move completed, false if not.
7436     */
7437    @Override
7438    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7439        enforceNotIsolatedCaller("moveActivityTaskToBack");
7440        synchronized(this) {
7441            final long origId = Binder.clearCallingIdentity();
7442            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7443            if (taskId >= 0) {
7444                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7445            }
7446            Binder.restoreCallingIdentity(origId);
7447        }
7448        return false;
7449    }
7450
7451    @Override
7452    public void moveTaskBackwards(int task) {
7453        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7454                "moveTaskBackwards()");
7455
7456        synchronized(this) {
7457            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7458                    Binder.getCallingUid(), "Task backwards")) {
7459                return;
7460            }
7461            final long origId = Binder.clearCallingIdentity();
7462            moveTaskBackwardsLocked(task);
7463            Binder.restoreCallingIdentity(origId);
7464        }
7465    }
7466
7467    private final void moveTaskBackwardsLocked(int task) {
7468        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7469    }
7470
7471    @Override
7472    public IBinder getHomeActivityToken() throws RemoteException {
7473        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7474                "getHomeActivityToken()");
7475        synchronized (this) {
7476            return mStackSupervisor.getHomeActivityToken();
7477        }
7478    }
7479
7480    @Override
7481    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7482            IActivityContainerCallback callback) throws RemoteException {
7483        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7484                "createActivityContainer()");
7485        synchronized (this) {
7486            if (parentActivityToken == null) {
7487                throw new IllegalArgumentException("parent token must not be null");
7488            }
7489            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7490            if (r == null) {
7491                return null;
7492            }
7493            if (callback == null) {
7494                throw new IllegalArgumentException("callback must not be null");
7495            }
7496            return mStackSupervisor.createActivityContainer(r, callback);
7497        }
7498    }
7499
7500    @Override
7501    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7502        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7503                "deleteActivityContainer()");
7504        synchronized (this) {
7505            mStackSupervisor.deleteActivityContainer(container);
7506        }
7507    }
7508
7509    @Override
7510    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7511            throws RemoteException {
7512        synchronized (this) {
7513            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7514            if (stack != null) {
7515                return stack.mActivityContainer;
7516            }
7517            return null;
7518        }
7519    }
7520
7521    @Override
7522    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7523        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7524                "moveTaskToStack()");
7525        if (stackId == HOME_STACK_ID) {
7526            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7527                    new RuntimeException("here").fillInStackTrace());
7528        }
7529        synchronized (this) {
7530            long ident = Binder.clearCallingIdentity();
7531            try {
7532                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7533                        + stackId + " toTop=" + toTop);
7534                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7535            } finally {
7536                Binder.restoreCallingIdentity(ident);
7537            }
7538        }
7539    }
7540
7541    @Override
7542    public void resizeStack(int stackBoxId, Rect bounds) {
7543        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7544                "resizeStackBox()");
7545        long ident = Binder.clearCallingIdentity();
7546        try {
7547            mWindowManager.resizeStack(stackBoxId, bounds);
7548        } finally {
7549            Binder.restoreCallingIdentity(ident);
7550        }
7551    }
7552
7553    @Override
7554    public List<StackInfo> getAllStackInfos() {
7555        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7556                "getAllStackInfos()");
7557        long ident = Binder.clearCallingIdentity();
7558        try {
7559            synchronized (this) {
7560                return mStackSupervisor.getAllStackInfosLocked();
7561            }
7562        } finally {
7563            Binder.restoreCallingIdentity(ident);
7564        }
7565    }
7566
7567    @Override
7568    public StackInfo getStackInfo(int stackId) {
7569        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7570                "getStackInfo()");
7571        long ident = Binder.clearCallingIdentity();
7572        try {
7573            synchronized (this) {
7574                return mStackSupervisor.getStackInfoLocked(stackId);
7575            }
7576        } finally {
7577            Binder.restoreCallingIdentity(ident);
7578        }
7579    }
7580
7581    @Override
7582    public boolean isInHomeStack(int taskId) {
7583        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7584                "getStackInfo()");
7585        long ident = Binder.clearCallingIdentity();
7586        try {
7587            synchronized (this) {
7588                TaskRecord tr = recentTaskForIdLocked(taskId);
7589                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7590            }
7591        } finally {
7592            Binder.restoreCallingIdentity(ident);
7593        }
7594    }
7595
7596    @Override
7597    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7598        synchronized(this) {
7599            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7600        }
7601    }
7602
7603    private boolean isLockTaskAuthorized(ComponentName name) {
7604        final DevicePolicyManager dpm = (DevicePolicyManager)
7605                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7606        return dpm != null && dpm.isLockTaskPermitted(name);
7607    }
7608
7609    private void startLockTaskMode(TaskRecord task) {
7610        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7611            return;
7612        }
7613        long ident = Binder.clearCallingIdentity();
7614        try {
7615            synchronized (this) {
7616                // Since we lost lock on task, make sure it is still there.
7617                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7618                if (task != null) {
7619                    mStackSupervisor.setLockTaskModeLocked(task);
7620                }
7621            }
7622        } finally {
7623            Binder.restoreCallingIdentity(ident);
7624        }
7625    }
7626
7627    @Override
7628    public void startLockTaskMode(int taskId) {
7629        long ident = Binder.clearCallingIdentity();
7630        try {
7631            final TaskRecord task;
7632            synchronized (this) {
7633                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7634            }
7635            if (task != null) {
7636                startLockTaskMode(task);
7637            }
7638        } finally {
7639            Binder.restoreCallingIdentity(ident);
7640        }
7641    }
7642
7643    @Override
7644    public void startLockTaskMode(IBinder token) {
7645        long ident = Binder.clearCallingIdentity();
7646        try {
7647            final TaskRecord task;
7648            synchronized (this) {
7649                final ActivityRecord r = ActivityRecord.forToken(token);
7650                if (r == null) {
7651                    return;
7652                }
7653                task = r.task;
7654            }
7655            if (task != null) {
7656                startLockTaskMode(task);
7657            }
7658        } finally {
7659            Binder.restoreCallingIdentity(ident);
7660        }
7661    }
7662
7663    @Override
7664    public void stopLockTaskMode() {
7665        // Check if the calling task is eligible to use lock task
7666        final int uid = Binder.getCallingUid();
7667        try {
7668            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7669            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7670                return;
7671            }
7672        } catch (RemoteException e) {
7673            Log.d(TAG, "stopLockTaskMode " + e);
7674            return;
7675        }
7676        // Stop lock task
7677        synchronized (this) {
7678            mStackSupervisor.setLockTaskModeLocked(null);
7679        }
7680    }
7681
7682    @Override
7683    public boolean isInLockTaskMode() {
7684        synchronized (this) {
7685            return mStackSupervisor.isInLockTaskMode();
7686        }
7687    }
7688
7689    // =========================================================
7690    // CONTENT PROVIDERS
7691    // =========================================================
7692
7693    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7694        List<ProviderInfo> providers = null;
7695        try {
7696            providers = AppGlobals.getPackageManager().
7697                queryContentProviders(app.processName, app.uid,
7698                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7699        } catch (RemoteException ex) {
7700        }
7701        if (DEBUG_MU)
7702            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7703        int userId = app.userId;
7704        if (providers != null) {
7705            int N = providers.size();
7706            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7707            for (int i=0; i<N; i++) {
7708                ProviderInfo cpi =
7709                    (ProviderInfo)providers.get(i);
7710                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7711                        cpi.name, cpi.flags);
7712                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7713                    // This is a singleton provider, but a user besides the
7714                    // default user is asking to initialize a process it runs
7715                    // in...  well, no, it doesn't actually run in this process,
7716                    // it runs in the process of the default user.  Get rid of it.
7717                    providers.remove(i);
7718                    N--;
7719                    i--;
7720                    continue;
7721                }
7722
7723                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7724                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7725                if (cpr == null) {
7726                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7727                    mProviderMap.putProviderByClass(comp, cpr);
7728                }
7729                if (DEBUG_MU)
7730                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7731                app.pubProviders.put(cpi.name, cpr);
7732                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7733                    // Don't add this if it is a platform component that is marked
7734                    // to run in multiple processes, because this is actually
7735                    // part of the framework so doesn't make sense to track as a
7736                    // separate apk in the process.
7737                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7738                }
7739                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7740            }
7741        }
7742        return providers;
7743    }
7744
7745    /**
7746     * Check if {@link ProcessRecord} has a possible chance at accessing the
7747     * given {@link ProviderInfo}. Final permission checking is always done
7748     * in {@link ContentProvider}.
7749     */
7750    private final String checkContentProviderPermissionLocked(
7751            ProviderInfo cpi, ProcessRecord r, int userId) {
7752        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7753        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7754        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7755        // Looking for cross-user grants before to enforce the typical cross-users permissions
7756        if (userId != UserHandle.getUserId(callingUid)) {
7757            if (perms != null) {
7758                for (GrantUri grantUri : perms.keySet()) {
7759                    if (grantUri.sourceUserId == userId) {
7760                        String authority = grantUri.uri.getAuthority();
7761                        if (authority.equals(cpi.authority)) {
7762                            return null;
7763                        }
7764                    }
7765                }
7766            }
7767        }
7768        userId = handleIncomingUser(callingPid, callingUid, userId,
7769                false, true, "checkContentProviderPermissionLocked", null);
7770        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7771                cpi.applicationInfo.uid, cpi.exported)
7772                == PackageManager.PERMISSION_GRANTED) {
7773            return null;
7774        }
7775        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7776                cpi.applicationInfo.uid, cpi.exported)
7777                == PackageManager.PERMISSION_GRANTED) {
7778            return null;
7779        }
7780
7781        PathPermission[] pps = cpi.pathPermissions;
7782        if (pps != null) {
7783            int i = pps.length;
7784            while (i > 0) {
7785                i--;
7786                PathPermission pp = pps[i];
7787                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7788                        cpi.applicationInfo.uid, cpi.exported)
7789                        == PackageManager.PERMISSION_GRANTED) {
7790                    return null;
7791                }
7792                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7793                        cpi.applicationInfo.uid, cpi.exported)
7794                        == PackageManager.PERMISSION_GRANTED) {
7795                    return null;
7796                }
7797            }
7798        }
7799
7800        if (perms != null) {
7801            for (GrantUri grantUri : perms.keySet()) {
7802                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7803                    return null;
7804                }
7805            }
7806        }
7807
7808        String msg;
7809        if (!cpi.exported) {
7810            msg = "Permission Denial: opening provider " + cpi.name
7811                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7812                    + ", uid=" + callingUid + ") that is not exported from uid "
7813                    + cpi.applicationInfo.uid;
7814        } else {
7815            msg = "Permission Denial: opening provider " + cpi.name
7816                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7817                    + ", uid=" + callingUid + ") requires "
7818                    + cpi.readPermission + " or " + cpi.writePermission;
7819        }
7820        Slog.w(TAG, msg);
7821        return msg;
7822    }
7823
7824    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7825            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7826        if (r != null) {
7827            for (int i=0; i<r.conProviders.size(); i++) {
7828                ContentProviderConnection conn = r.conProviders.get(i);
7829                if (conn.provider == cpr) {
7830                    if (DEBUG_PROVIDER) Slog.v(TAG,
7831                            "Adding provider requested by "
7832                            + r.processName + " from process "
7833                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7834                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7835                    if (stable) {
7836                        conn.stableCount++;
7837                        conn.numStableIncs++;
7838                    } else {
7839                        conn.unstableCount++;
7840                        conn.numUnstableIncs++;
7841                    }
7842                    return conn;
7843                }
7844            }
7845            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7846            if (stable) {
7847                conn.stableCount = 1;
7848                conn.numStableIncs = 1;
7849            } else {
7850                conn.unstableCount = 1;
7851                conn.numUnstableIncs = 1;
7852            }
7853            cpr.connections.add(conn);
7854            r.conProviders.add(conn);
7855            return conn;
7856        }
7857        cpr.addExternalProcessHandleLocked(externalProcessToken);
7858        return null;
7859    }
7860
7861    boolean decProviderCountLocked(ContentProviderConnection conn,
7862            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7863        if (conn != null) {
7864            cpr = conn.provider;
7865            if (DEBUG_PROVIDER) Slog.v(TAG,
7866                    "Removing provider requested by "
7867                    + conn.client.processName + " from process "
7868                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7869                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7870            if (stable) {
7871                conn.stableCount--;
7872            } else {
7873                conn.unstableCount--;
7874            }
7875            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7876                cpr.connections.remove(conn);
7877                conn.client.conProviders.remove(conn);
7878                return true;
7879            }
7880            return false;
7881        }
7882        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7883        return false;
7884    }
7885
7886    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7887            String name, IBinder token, boolean stable, int userId) {
7888        ContentProviderRecord cpr;
7889        ContentProviderConnection conn = null;
7890        ProviderInfo cpi = null;
7891
7892        synchronized(this) {
7893            ProcessRecord r = null;
7894            if (caller != null) {
7895                r = getRecordForAppLocked(caller);
7896                if (r == null) {
7897                    throw new SecurityException(
7898                            "Unable to find app for caller " + caller
7899                          + " (pid=" + Binder.getCallingPid()
7900                          + ") when getting content provider " + name);
7901                }
7902            }
7903
7904            // First check if this content provider has been published...
7905            cpr = mProviderMap.getProviderByName(name, userId);
7906            boolean providerRunning = cpr != null;
7907            if (providerRunning) {
7908                cpi = cpr.info;
7909                String msg;
7910                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7911                    throw new SecurityException(msg);
7912                }
7913
7914                if (r != null && cpr.canRunHere(r)) {
7915                    // This provider has been published or is in the process
7916                    // of being published...  but it is also allowed to run
7917                    // in the caller's process, so don't make a connection
7918                    // and just let the caller instantiate its own instance.
7919                    ContentProviderHolder holder = cpr.newHolder(null);
7920                    // don't give caller the provider object, it needs
7921                    // to make its own.
7922                    holder.provider = null;
7923                    return holder;
7924                }
7925
7926                final long origId = Binder.clearCallingIdentity();
7927
7928                // In this case the provider instance already exists, so we can
7929                // return it right away.
7930                conn = incProviderCountLocked(r, cpr, token, stable);
7931                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7932                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7933                        // If this is a perceptible app accessing the provider,
7934                        // make sure to count it as being accessed and thus
7935                        // back up on the LRU list.  This is good because
7936                        // content providers are often expensive to start.
7937                        updateLruProcessLocked(cpr.proc, false, null);
7938                    }
7939                }
7940
7941                if (cpr.proc != null) {
7942                    if (false) {
7943                        if (cpr.name.flattenToShortString().equals(
7944                                "com.android.providers.calendar/.CalendarProvider2")) {
7945                            Slog.v(TAG, "****************** KILLING "
7946                                + cpr.name.flattenToShortString());
7947                            Process.killProcess(cpr.proc.pid);
7948                        }
7949                    }
7950                    boolean success = updateOomAdjLocked(cpr.proc);
7951                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7952                    // NOTE: there is still a race here where a signal could be
7953                    // pending on the process even though we managed to update its
7954                    // adj level.  Not sure what to do about this, but at least
7955                    // the race is now smaller.
7956                    if (!success) {
7957                        // Uh oh...  it looks like the provider's process
7958                        // has been killed on us.  We need to wait for a new
7959                        // process to be started, and make sure its death
7960                        // doesn't kill our process.
7961                        Slog.i(TAG,
7962                                "Existing provider " + cpr.name.flattenToShortString()
7963                                + " is crashing; detaching " + r);
7964                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7965                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7966                        if (!lastRef) {
7967                            // This wasn't the last ref our process had on
7968                            // the provider...  we have now been killed, bail.
7969                            return null;
7970                        }
7971                        providerRunning = false;
7972                        conn = null;
7973                    }
7974                }
7975
7976                Binder.restoreCallingIdentity(origId);
7977            }
7978
7979            boolean singleton;
7980            if (!providerRunning) {
7981                try {
7982                    cpi = AppGlobals.getPackageManager().
7983                        resolveContentProvider(name,
7984                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7985                } catch (RemoteException ex) {
7986                }
7987                if (cpi == null) {
7988                    return null;
7989                }
7990                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7991                        cpi.name, cpi.flags);
7992                if (singleton) {
7993                    userId = 0;
7994                }
7995                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7996
7997                String msg;
7998                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7999                    throw new SecurityException(msg);
8000                }
8001
8002                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8003                        && !cpi.processName.equals("system")) {
8004                    // If this content provider does not run in the system
8005                    // process, and the system is not yet ready to run other
8006                    // processes, then fail fast instead of hanging.
8007                    throw new IllegalArgumentException(
8008                            "Attempt to launch content provider before system ready");
8009                }
8010
8011                // Make sure that the user who owns this provider is started.  If not,
8012                // we don't want to allow it to run.
8013                if (mStartedUsers.get(userId) == null) {
8014                    Slog.w(TAG, "Unable to launch app "
8015                            + cpi.applicationInfo.packageName + "/"
8016                            + cpi.applicationInfo.uid + " for provider "
8017                            + name + ": user " + userId + " is stopped");
8018                    return null;
8019                }
8020
8021                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8022                cpr = mProviderMap.getProviderByClass(comp, userId);
8023                final boolean firstClass = cpr == null;
8024                if (firstClass) {
8025                    try {
8026                        ApplicationInfo ai =
8027                            AppGlobals.getPackageManager().
8028                                getApplicationInfo(
8029                                        cpi.applicationInfo.packageName,
8030                                        STOCK_PM_FLAGS, userId);
8031                        if (ai == null) {
8032                            Slog.w(TAG, "No package info for content provider "
8033                                    + cpi.name);
8034                            return null;
8035                        }
8036                        ai = getAppInfoForUser(ai, userId);
8037                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8038                    } catch (RemoteException ex) {
8039                        // pm is in same process, this will never happen.
8040                    }
8041                }
8042
8043                if (r != null && cpr.canRunHere(r)) {
8044                    // If this is a multiprocess provider, then just return its
8045                    // info and allow the caller to instantiate it.  Only do
8046                    // this if the provider is the same user as the caller's
8047                    // process, or can run as root (so can be in any process).
8048                    return cpr.newHolder(null);
8049                }
8050
8051                if (DEBUG_PROVIDER) {
8052                    RuntimeException e = new RuntimeException("here");
8053                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8054                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8055                }
8056
8057                // This is single process, and our app is now connecting to it.
8058                // See if we are already in the process of launching this
8059                // provider.
8060                final int N = mLaunchingProviders.size();
8061                int i;
8062                for (i=0; i<N; i++) {
8063                    if (mLaunchingProviders.get(i) == cpr) {
8064                        break;
8065                    }
8066                }
8067
8068                // If the provider is not already being launched, then get it
8069                // started.
8070                if (i >= N) {
8071                    final long origId = Binder.clearCallingIdentity();
8072
8073                    try {
8074                        // Content provider is now in use, its package can't be stopped.
8075                        try {
8076                            AppGlobals.getPackageManager().setPackageStoppedState(
8077                                    cpr.appInfo.packageName, false, userId);
8078                        } catch (RemoteException e) {
8079                        } catch (IllegalArgumentException e) {
8080                            Slog.w(TAG, "Failed trying to unstop package "
8081                                    + cpr.appInfo.packageName + ": " + e);
8082                        }
8083
8084                        // Use existing process if already started
8085                        ProcessRecord proc = getProcessRecordLocked(
8086                                cpi.processName, cpr.appInfo.uid, false);
8087                        if (proc != null && proc.thread != null) {
8088                            if (DEBUG_PROVIDER) {
8089                                Slog.d(TAG, "Installing in existing process " + proc);
8090                            }
8091                            proc.pubProviders.put(cpi.name, cpr);
8092                            try {
8093                                proc.thread.scheduleInstallProvider(cpi);
8094                            } catch (RemoteException e) {
8095                            }
8096                        } else {
8097                            proc = startProcessLocked(cpi.processName,
8098                                    cpr.appInfo, false, 0, "content provider",
8099                                    new ComponentName(cpi.applicationInfo.packageName,
8100                                            cpi.name), false, false, false);
8101                            if (proc == null) {
8102                                Slog.w(TAG, "Unable to launch app "
8103                                        + cpi.applicationInfo.packageName + "/"
8104                                        + cpi.applicationInfo.uid + " for provider "
8105                                        + name + ": process is bad");
8106                                return null;
8107                            }
8108                        }
8109                        cpr.launchingApp = proc;
8110                        mLaunchingProviders.add(cpr);
8111                    } finally {
8112                        Binder.restoreCallingIdentity(origId);
8113                    }
8114                }
8115
8116                // Make sure the provider is published (the same provider class
8117                // may be published under multiple names).
8118                if (firstClass) {
8119                    mProviderMap.putProviderByClass(comp, cpr);
8120                }
8121
8122                mProviderMap.putProviderByName(name, cpr);
8123                conn = incProviderCountLocked(r, cpr, token, stable);
8124                if (conn != null) {
8125                    conn.waiting = true;
8126                }
8127            }
8128        }
8129
8130        // Wait for the provider to be published...
8131        synchronized (cpr) {
8132            while (cpr.provider == null) {
8133                if (cpr.launchingApp == null) {
8134                    Slog.w(TAG, "Unable to launch app "
8135                            + cpi.applicationInfo.packageName + "/"
8136                            + cpi.applicationInfo.uid + " for provider "
8137                            + name + ": launching app became null");
8138                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8139                            UserHandle.getUserId(cpi.applicationInfo.uid),
8140                            cpi.applicationInfo.packageName,
8141                            cpi.applicationInfo.uid, name);
8142                    return null;
8143                }
8144                try {
8145                    if (DEBUG_MU) {
8146                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8147                                + cpr.launchingApp);
8148                    }
8149                    if (conn != null) {
8150                        conn.waiting = true;
8151                    }
8152                    cpr.wait();
8153                } catch (InterruptedException ex) {
8154                } finally {
8155                    if (conn != null) {
8156                        conn.waiting = false;
8157                    }
8158                }
8159            }
8160        }
8161        return cpr != null ? cpr.newHolder(conn) : null;
8162    }
8163
8164    @Override
8165    public final ContentProviderHolder getContentProvider(
8166            IApplicationThread caller, String name, int userId, boolean stable) {
8167        enforceNotIsolatedCaller("getContentProvider");
8168        if (caller == null) {
8169            String msg = "null IApplicationThread when getting content provider "
8170                    + name;
8171            Slog.w(TAG, msg);
8172            throw new SecurityException(msg);
8173        }
8174        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8175        // with cross-user grant.
8176        return getContentProviderImpl(caller, name, null, stable, userId);
8177    }
8178
8179    public ContentProviderHolder getContentProviderExternal(
8180            String name, int userId, IBinder token) {
8181        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8182            "Do not have permission in call getContentProviderExternal()");
8183        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8184                false, true, "getContentProvider", null);
8185        return getContentProviderExternalUnchecked(name, token, userId);
8186    }
8187
8188    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8189            IBinder token, int userId) {
8190        return getContentProviderImpl(null, name, token, true, userId);
8191    }
8192
8193    /**
8194     * Drop a content provider from a ProcessRecord's bookkeeping
8195     */
8196    public void removeContentProvider(IBinder connection, boolean stable) {
8197        enforceNotIsolatedCaller("removeContentProvider");
8198        long ident = Binder.clearCallingIdentity();
8199        try {
8200            synchronized (this) {
8201                ContentProviderConnection conn;
8202                try {
8203                    conn = (ContentProviderConnection)connection;
8204                } catch (ClassCastException e) {
8205                    String msg ="removeContentProvider: " + connection
8206                            + " not a ContentProviderConnection";
8207                    Slog.w(TAG, msg);
8208                    throw new IllegalArgumentException(msg);
8209                }
8210                if (conn == null) {
8211                    throw new NullPointerException("connection is null");
8212                }
8213                if (decProviderCountLocked(conn, null, null, stable)) {
8214                    updateOomAdjLocked();
8215                }
8216            }
8217        } finally {
8218            Binder.restoreCallingIdentity(ident);
8219        }
8220    }
8221
8222    public void removeContentProviderExternal(String name, IBinder token) {
8223        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8224            "Do not have permission in call removeContentProviderExternal()");
8225        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8226    }
8227
8228    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8229        synchronized (this) {
8230            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8231            if(cpr == null) {
8232                //remove from mProvidersByClass
8233                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8234                return;
8235            }
8236
8237            //update content provider record entry info
8238            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8239            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8240            if (localCpr.hasExternalProcessHandles()) {
8241                if (localCpr.removeExternalProcessHandleLocked(token)) {
8242                    updateOomAdjLocked();
8243                } else {
8244                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8245                            + " with no external reference for token: "
8246                            + token + ".");
8247                }
8248            } else {
8249                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8250                        + " with no external references.");
8251            }
8252        }
8253    }
8254
8255    public final void publishContentProviders(IApplicationThread caller,
8256            List<ContentProviderHolder> providers) {
8257        if (providers == null) {
8258            return;
8259        }
8260
8261        enforceNotIsolatedCaller("publishContentProviders");
8262        synchronized (this) {
8263            final ProcessRecord r = getRecordForAppLocked(caller);
8264            if (DEBUG_MU)
8265                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8266            if (r == null) {
8267                throw new SecurityException(
8268                        "Unable to find app for caller " + caller
8269                      + " (pid=" + Binder.getCallingPid()
8270                      + ") when publishing content providers");
8271            }
8272
8273            final long origId = Binder.clearCallingIdentity();
8274
8275            final int N = providers.size();
8276            for (int i=0; i<N; i++) {
8277                ContentProviderHolder src = providers.get(i);
8278                if (src == null || src.info == null || src.provider == null) {
8279                    continue;
8280                }
8281                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8282                if (DEBUG_MU)
8283                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8284                if (dst != null) {
8285                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8286                    mProviderMap.putProviderByClass(comp, dst);
8287                    String names[] = dst.info.authority.split(";");
8288                    for (int j = 0; j < names.length; j++) {
8289                        mProviderMap.putProviderByName(names[j], dst);
8290                    }
8291
8292                    int NL = mLaunchingProviders.size();
8293                    int j;
8294                    for (j=0; j<NL; j++) {
8295                        if (mLaunchingProviders.get(j) == dst) {
8296                            mLaunchingProviders.remove(j);
8297                            j--;
8298                            NL--;
8299                        }
8300                    }
8301                    synchronized (dst) {
8302                        dst.provider = src.provider;
8303                        dst.proc = r;
8304                        dst.notifyAll();
8305                    }
8306                    updateOomAdjLocked(r);
8307                }
8308            }
8309
8310            Binder.restoreCallingIdentity(origId);
8311        }
8312    }
8313
8314    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8315        ContentProviderConnection conn;
8316        try {
8317            conn = (ContentProviderConnection)connection;
8318        } catch (ClassCastException e) {
8319            String msg ="refContentProvider: " + connection
8320                    + " not a ContentProviderConnection";
8321            Slog.w(TAG, msg);
8322            throw new IllegalArgumentException(msg);
8323        }
8324        if (conn == null) {
8325            throw new NullPointerException("connection is null");
8326        }
8327
8328        synchronized (this) {
8329            if (stable > 0) {
8330                conn.numStableIncs += stable;
8331            }
8332            stable = conn.stableCount + stable;
8333            if (stable < 0) {
8334                throw new IllegalStateException("stableCount < 0: " + stable);
8335            }
8336
8337            if (unstable > 0) {
8338                conn.numUnstableIncs += unstable;
8339            }
8340            unstable = conn.unstableCount + unstable;
8341            if (unstable < 0) {
8342                throw new IllegalStateException("unstableCount < 0: " + unstable);
8343            }
8344
8345            if ((stable+unstable) <= 0) {
8346                throw new IllegalStateException("ref counts can't go to zero here: stable="
8347                        + stable + " unstable=" + unstable);
8348            }
8349            conn.stableCount = stable;
8350            conn.unstableCount = unstable;
8351            return !conn.dead;
8352        }
8353    }
8354
8355    public void unstableProviderDied(IBinder connection) {
8356        ContentProviderConnection conn;
8357        try {
8358            conn = (ContentProviderConnection)connection;
8359        } catch (ClassCastException e) {
8360            String msg ="refContentProvider: " + connection
8361                    + " not a ContentProviderConnection";
8362            Slog.w(TAG, msg);
8363            throw new IllegalArgumentException(msg);
8364        }
8365        if (conn == null) {
8366            throw new NullPointerException("connection is null");
8367        }
8368
8369        // Safely retrieve the content provider associated with the connection.
8370        IContentProvider provider;
8371        synchronized (this) {
8372            provider = conn.provider.provider;
8373        }
8374
8375        if (provider == null) {
8376            // Um, yeah, we're way ahead of you.
8377            return;
8378        }
8379
8380        // Make sure the caller is being honest with us.
8381        if (provider.asBinder().pingBinder()) {
8382            // Er, no, still looks good to us.
8383            synchronized (this) {
8384                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8385                        + " says " + conn + " died, but we don't agree");
8386                return;
8387            }
8388        }
8389
8390        // Well look at that!  It's dead!
8391        synchronized (this) {
8392            if (conn.provider.provider != provider) {
8393                // But something changed...  good enough.
8394                return;
8395            }
8396
8397            ProcessRecord proc = conn.provider.proc;
8398            if (proc == null || proc.thread == null) {
8399                // Seems like the process is already cleaned up.
8400                return;
8401            }
8402
8403            // As far as we're concerned, this is just like receiving a
8404            // death notification...  just a bit prematurely.
8405            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8406                    + ") early provider death");
8407            final long ident = Binder.clearCallingIdentity();
8408            try {
8409                appDiedLocked(proc, proc.pid, proc.thread);
8410            } finally {
8411                Binder.restoreCallingIdentity(ident);
8412            }
8413        }
8414    }
8415
8416    @Override
8417    public void appNotRespondingViaProvider(IBinder connection) {
8418        enforceCallingPermission(
8419                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8420
8421        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8422        if (conn == null) {
8423            Slog.w(TAG, "ContentProviderConnection is null");
8424            return;
8425        }
8426
8427        final ProcessRecord host = conn.provider.proc;
8428        if (host == null) {
8429            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8430            return;
8431        }
8432
8433        final long token = Binder.clearCallingIdentity();
8434        try {
8435            appNotResponding(host, null, null, false, "ContentProvider not responding");
8436        } finally {
8437            Binder.restoreCallingIdentity(token);
8438        }
8439    }
8440
8441    public final void installSystemProviders() {
8442        List<ProviderInfo> providers;
8443        synchronized (this) {
8444            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8445            providers = generateApplicationProvidersLocked(app);
8446            if (providers != null) {
8447                for (int i=providers.size()-1; i>=0; i--) {
8448                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8449                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8450                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8451                                + ": not system .apk");
8452                        providers.remove(i);
8453                    }
8454                }
8455            }
8456        }
8457        if (providers != null) {
8458            mSystemThread.installSystemProviders(providers);
8459        }
8460
8461        mCoreSettingsObserver = new CoreSettingsObserver(this);
8462
8463        mUsageStatsService.monitorPackages();
8464    }
8465
8466    /**
8467     * Allows app to retrieve the MIME type of a URI without having permission
8468     * to access its content provider.
8469     *
8470     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8471     *
8472     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8473     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8474     */
8475    public String getProviderMimeType(Uri uri, int userId) {
8476        enforceNotIsolatedCaller("getProviderMimeType");
8477        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8478                userId, false, true, "getProviderMimeType", null);
8479        final String name = uri.getAuthority();
8480        final long ident = Binder.clearCallingIdentity();
8481        ContentProviderHolder holder = null;
8482
8483        try {
8484            holder = getContentProviderExternalUnchecked(name, null, userId);
8485            if (holder != null) {
8486                return holder.provider.getType(uri);
8487            }
8488        } catch (RemoteException e) {
8489            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8490            return null;
8491        } finally {
8492            if (holder != null) {
8493                removeContentProviderExternalUnchecked(name, null, userId);
8494            }
8495            Binder.restoreCallingIdentity(ident);
8496        }
8497
8498        return null;
8499    }
8500
8501    // =========================================================
8502    // GLOBAL MANAGEMENT
8503    // =========================================================
8504
8505    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8506            boolean isolated) {
8507        String proc = customProcess != null ? customProcess : info.processName;
8508        BatteryStatsImpl.Uid.Proc ps = null;
8509        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8510        int uid = info.uid;
8511        if (isolated) {
8512            int userId = UserHandle.getUserId(uid);
8513            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8514            while (true) {
8515                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8516                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8517                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8518                }
8519                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8520                mNextIsolatedProcessUid++;
8521                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8522                    // No process for this uid, use it.
8523                    break;
8524                }
8525                stepsLeft--;
8526                if (stepsLeft <= 0) {
8527                    return null;
8528                }
8529            }
8530        }
8531        return new ProcessRecord(stats, info, proc, uid);
8532    }
8533
8534    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8535        ProcessRecord app;
8536        if (!isolated) {
8537            app = getProcessRecordLocked(info.processName, info.uid, true);
8538        } else {
8539            app = null;
8540        }
8541
8542        if (app == null) {
8543            app = newProcessRecordLocked(info, null, isolated);
8544            mProcessNames.put(info.processName, app.uid, app);
8545            if (isolated) {
8546                mIsolatedProcesses.put(app.uid, app);
8547            }
8548            updateLruProcessLocked(app, false, null);
8549            updateOomAdjLocked();
8550        }
8551
8552        // This package really, really can not be stopped.
8553        try {
8554            AppGlobals.getPackageManager().setPackageStoppedState(
8555                    info.packageName, false, UserHandle.getUserId(app.uid));
8556        } catch (RemoteException e) {
8557        } catch (IllegalArgumentException e) {
8558            Slog.w(TAG, "Failed trying to unstop package "
8559                    + info.packageName + ": " + e);
8560        }
8561
8562        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8563                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8564            app.persistent = true;
8565            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8566        }
8567        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8568            mPersistentStartingProcesses.add(app);
8569            startProcessLocked(app, "added application", app.processName);
8570        }
8571
8572        return app;
8573    }
8574
8575    public void unhandledBack() {
8576        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8577                "unhandledBack()");
8578
8579        synchronized(this) {
8580            final long origId = Binder.clearCallingIdentity();
8581            try {
8582                getFocusedStack().unhandledBackLocked();
8583            } finally {
8584                Binder.restoreCallingIdentity(origId);
8585            }
8586        }
8587    }
8588
8589    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8590        enforceNotIsolatedCaller("openContentUri");
8591        final int userId = UserHandle.getCallingUserId();
8592        String name = uri.getAuthority();
8593        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8594        ParcelFileDescriptor pfd = null;
8595        if (cph != null) {
8596            // We record the binder invoker's uid in thread-local storage before
8597            // going to the content provider to open the file.  Later, in the code
8598            // that handles all permissions checks, we look for this uid and use
8599            // that rather than the Activity Manager's own uid.  The effect is that
8600            // we do the check against the caller's permissions even though it looks
8601            // to the content provider like the Activity Manager itself is making
8602            // the request.
8603            sCallerIdentity.set(new Identity(
8604                    Binder.getCallingPid(), Binder.getCallingUid()));
8605            try {
8606                pfd = cph.provider.openFile(null, uri, "r", null);
8607            } catch (FileNotFoundException e) {
8608                // do nothing; pfd will be returned null
8609            } finally {
8610                // Ensure that whatever happens, we clean up the identity state
8611                sCallerIdentity.remove();
8612            }
8613
8614            // We've got the fd now, so we're done with the provider.
8615            removeContentProviderExternalUnchecked(name, null, userId);
8616        } else {
8617            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8618        }
8619        return pfd;
8620    }
8621
8622    // Actually is sleeping or shutting down or whatever else in the future
8623    // is an inactive state.
8624    public boolean isSleepingOrShuttingDown() {
8625        return mSleeping || mShuttingDown;
8626    }
8627
8628    public boolean isSleeping() {
8629        return mSleeping;
8630    }
8631
8632    void goingToSleep() {
8633        synchronized(this) {
8634            mWentToSleep = true;
8635            updateEventDispatchingLocked();
8636            goToSleepIfNeededLocked();
8637        }
8638    }
8639
8640    void finishRunningVoiceLocked() {
8641        if (mRunningVoice) {
8642            mRunningVoice = false;
8643            goToSleepIfNeededLocked();
8644        }
8645    }
8646
8647    void goToSleepIfNeededLocked() {
8648        if (mWentToSleep && !mRunningVoice) {
8649            if (!mSleeping) {
8650                mSleeping = true;
8651                mStackSupervisor.goingToSleepLocked();
8652
8653                // Initialize the wake times of all processes.
8654                checkExcessivePowerUsageLocked(false);
8655                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8656                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8657                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8658            }
8659        }
8660    }
8661
8662    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8663        mTaskPersister.notify(task, flush);
8664    }
8665
8666    @Override
8667    public boolean shutdown(int timeout) {
8668        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8669                != PackageManager.PERMISSION_GRANTED) {
8670            throw new SecurityException("Requires permission "
8671                    + android.Manifest.permission.SHUTDOWN);
8672        }
8673
8674        boolean timedout = false;
8675
8676        synchronized(this) {
8677            mShuttingDown = true;
8678            updateEventDispatchingLocked();
8679            timedout = mStackSupervisor.shutdownLocked(timeout);
8680        }
8681
8682        mAppOpsService.shutdown();
8683        mUsageStatsService.shutdown();
8684        mBatteryStatsService.shutdown();
8685        synchronized (this) {
8686            mProcessStats.shutdownLocked();
8687        }
8688        notifyTaskPersisterLocked(null, true);
8689
8690        return timedout;
8691    }
8692
8693    public final void activitySlept(IBinder token) {
8694        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8695
8696        final long origId = Binder.clearCallingIdentity();
8697
8698        synchronized (this) {
8699            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8700            if (r != null) {
8701                mStackSupervisor.activitySleptLocked(r);
8702            }
8703        }
8704
8705        Binder.restoreCallingIdentity(origId);
8706    }
8707
8708    void logLockScreen(String msg) {
8709        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8710                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8711                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8712                mStackSupervisor.mDismissKeyguardOnNextActivity);
8713    }
8714
8715    private void comeOutOfSleepIfNeededLocked() {
8716        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8717            if (mSleeping) {
8718                mSleeping = false;
8719                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8720            }
8721        }
8722    }
8723
8724    void wakingUp() {
8725        synchronized(this) {
8726            mWentToSleep = false;
8727            updateEventDispatchingLocked();
8728            comeOutOfSleepIfNeededLocked();
8729        }
8730    }
8731
8732    void startRunningVoiceLocked() {
8733        if (!mRunningVoice) {
8734            mRunningVoice = true;
8735            comeOutOfSleepIfNeededLocked();
8736        }
8737    }
8738
8739    private void updateEventDispatchingLocked() {
8740        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8741    }
8742
8743    public void setLockScreenShown(boolean shown) {
8744        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8745                != PackageManager.PERMISSION_GRANTED) {
8746            throw new SecurityException("Requires permission "
8747                    + android.Manifest.permission.DEVICE_POWER);
8748        }
8749
8750        synchronized(this) {
8751            long ident = Binder.clearCallingIdentity();
8752            try {
8753                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8754                mLockScreenShown = shown;
8755                comeOutOfSleepIfNeededLocked();
8756            } finally {
8757                Binder.restoreCallingIdentity(ident);
8758            }
8759        }
8760    }
8761
8762    public void stopAppSwitches() {
8763        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8764                != PackageManager.PERMISSION_GRANTED) {
8765            throw new SecurityException("Requires permission "
8766                    + android.Manifest.permission.STOP_APP_SWITCHES);
8767        }
8768
8769        synchronized(this) {
8770            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8771                    + APP_SWITCH_DELAY_TIME;
8772            mDidAppSwitch = false;
8773            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8774            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8775            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8776        }
8777    }
8778
8779    public void resumeAppSwitches() {
8780        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8781                != PackageManager.PERMISSION_GRANTED) {
8782            throw new SecurityException("Requires permission "
8783                    + android.Manifest.permission.STOP_APP_SWITCHES);
8784        }
8785
8786        synchronized(this) {
8787            // Note that we don't execute any pending app switches... we will
8788            // let those wait until either the timeout, or the next start
8789            // activity request.
8790            mAppSwitchesAllowedTime = 0;
8791        }
8792    }
8793
8794    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8795            String name) {
8796        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8797            return true;
8798        }
8799
8800        final int perm = checkComponentPermission(
8801                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8802                callingUid, -1, true);
8803        if (perm == PackageManager.PERMISSION_GRANTED) {
8804            return true;
8805        }
8806
8807        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8808        return false;
8809    }
8810
8811    public void setDebugApp(String packageName, boolean waitForDebugger,
8812            boolean persistent) {
8813        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8814                "setDebugApp()");
8815
8816        long ident = Binder.clearCallingIdentity();
8817        try {
8818            // Note that this is not really thread safe if there are multiple
8819            // callers into it at the same time, but that's not a situation we
8820            // care about.
8821            if (persistent) {
8822                final ContentResolver resolver = mContext.getContentResolver();
8823                Settings.Global.putString(
8824                    resolver, Settings.Global.DEBUG_APP,
8825                    packageName);
8826                Settings.Global.putInt(
8827                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8828                    waitForDebugger ? 1 : 0);
8829            }
8830
8831            synchronized (this) {
8832                if (!persistent) {
8833                    mOrigDebugApp = mDebugApp;
8834                    mOrigWaitForDebugger = mWaitForDebugger;
8835                }
8836                mDebugApp = packageName;
8837                mWaitForDebugger = waitForDebugger;
8838                mDebugTransient = !persistent;
8839                if (packageName != null) {
8840                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8841                            false, UserHandle.USER_ALL, "set debug app");
8842                }
8843            }
8844        } finally {
8845            Binder.restoreCallingIdentity(ident);
8846        }
8847    }
8848
8849    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8850        synchronized (this) {
8851            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8852            if (!isDebuggable) {
8853                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8854                    throw new SecurityException("Process not debuggable: " + app.packageName);
8855                }
8856            }
8857
8858            mOpenGlTraceApp = processName;
8859        }
8860    }
8861
8862    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8863            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8864        synchronized (this) {
8865            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8866            if (!isDebuggable) {
8867                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8868                    throw new SecurityException("Process not debuggable: " + app.packageName);
8869                }
8870            }
8871            mProfileApp = processName;
8872            mProfileFile = profileFile;
8873            if (mProfileFd != null) {
8874                try {
8875                    mProfileFd.close();
8876                } catch (IOException e) {
8877                }
8878                mProfileFd = null;
8879            }
8880            mProfileFd = profileFd;
8881            mProfileType = 0;
8882            mAutoStopProfiler = autoStopProfiler;
8883        }
8884    }
8885
8886    @Override
8887    public void setAlwaysFinish(boolean enabled) {
8888        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8889                "setAlwaysFinish()");
8890
8891        Settings.Global.putInt(
8892                mContext.getContentResolver(),
8893                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8894
8895        synchronized (this) {
8896            mAlwaysFinishActivities = enabled;
8897        }
8898    }
8899
8900    @Override
8901    public void setActivityController(IActivityController controller) {
8902        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8903                "setActivityController()");
8904        synchronized (this) {
8905            mController = controller;
8906            Watchdog.getInstance().setActivityController(controller);
8907        }
8908    }
8909
8910    @Override
8911    public void setUserIsMonkey(boolean userIsMonkey) {
8912        synchronized (this) {
8913            synchronized (mPidsSelfLocked) {
8914                final int callingPid = Binder.getCallingPid();
8915                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8916                if (precessRecord == null) {
8917                    throw new SecurityException("Unknown process: " + callingPid);
8918                }
8919                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8920                    throw new SecurityException("Only an instrumentation process "
8921                            + "with a UiAutomation can call setUserIsMonkey");
8922                }
8923            }
8924            mUserIsMonkey = userIsMonkey;
8925        }
8926    }
8927
8928    @Override
8929    public boolean isUserAMonkey() {
8930        synchronized (this) {
8931            // If there is a controller also implies the user is a monkey.
8932            return (mUserIsMonkey || mController != null);
8933        }
8934    }
8935
8936    public void requestBugReport() {
8937        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8938        SystemProperties.set("ctl.start", "bugreport");
8939    }
8940
8941    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8942        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8943    }
8944
8945    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8946        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8947            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8948        }
8949        return KEY_DISPATCHING_TIMEOUT;
8950    }
8951
8952    @Override
8953    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8954        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8955                != PackageManager.PERMISSION_GRANTED) {
8956            throw new SecurityException("Requires permission "
8957                    + android.Manifest.permission.FILTER_EVENTS);
8958        }
8959        ProcessRecord proc;
8960        long timeout;
8961        synchronized (this) {
8962            synchronized (mPidsSelfLocked) {
8963                proc = mPidsSelfLocked.get(pid);
8964            }
8965            timeout = getInputDispatchingTimeoutLocked(proc);
8966        }
8967
8968        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8969            return -1;
8970        }
8971
8972        return timeout;
8973    }
8974
8975    /**
8976     * Handle input dispatching timeouts.
8977     * Returns whether input dispatching should be aborted or not.
8978     */
8979    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8980            final ActivityRecord activity, final ActivityRecord parent,
8981            final boolean aboveSystem, String reason) {
8982        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8983                != PackageManager.PERMISSION_GRANTED) {
8984            throw new SecurityException("Requires permission "
8985                    + android.Manifest.permission.FILTER_EVENTS);
8986        }
8987
8988        final String annotation;
8989        if (reason == null) {
8990            annotation = "Input dispatching timed out";
8991        } else {
8992            annotation = "Input dispatching timed out (" + reason + ")";
8993        }
8994
8995        if (proc != null) {
8996            synchronized (this) {
8997                if (proc.debugging) {
8998                    return false;
8999                }
9000
9001                if (mDidDexOpt) {
9002                    // Give more time since we were dexopting.
9003                    mDidDexOpt = false;
9004                    return false;
9005                }
9006
9007                if (proc.instrumentationClass != null) {
9008                    Bundle info = new Bundle();
9009                    info.putString("shortMsg", "keyDispatchingTimedOut");
9010                    info.putString("longMsg", annotation);
9011                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9012                    return true;
9013                }
9014            }
9015            mHandler.post(new Runnable() {
9016                @Override
9017                public void run() {
9018                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9019                }
9020            });
9021        }
9022
9023        return true;
9024    }
9025
9026    public Bundle getAssistContextExtras(int requestType) {
9027        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9028                "getAssistContextExtras()");
9029        PendingAssistExtras pae;
9030        Bundle extras = new Bundle();
9031        synchronized (this) {
9032            ActivityRecord activity = getFocusedStack().mResumedActivity;
9033            if (activity == null) {
9034                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9035                return null;
9036            }
9037            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9038            if (activity.app == null || activity.app.thread == null) {
9039                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9040                return extras;
9041            }
9042            if (activity.app.pid == Binder.getCallingPid()) {
9043                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9044                return extras;
9045            }
9046            pae = new PendingAssistExtras(activity);
9047            try {
9048                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9049                        requestType);
9050                mPendingAssistExtras.add(pae);
9051                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9052            } catch (RemoteException e) {
9053                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9054                return extras;
9055            }
9056        }
9057        synchronized (pae) {
9058            while (!pae.haveResult) {
9059                try {
9060                    pae.wait();
9061                } catch (InterruptedException e) {
9062                }
9063            }
9064            if (pae.result != null) {
9065                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9066            }
9067        }
9068        synchronized (this) {
9069            mPendingAssistExtras.remove(pae);
9070            mHandler.removeCallbacks(pae);
9071        }
9072        return extras;
9073    }
9074
9075    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9076        PendingAssistExtras pae = (PendingAssistExtras)token;
9077        synchronized (pae) {
9078            pae.result = extras;
9079            pae.haveResult = true;
9080            pae.notifyAll();
9081        }
9082    }
9083
9084    public void registerProcessObserver(IProcessObserver observer) {
9085        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9086                "registerProcessObserver()");
9087        synchronized (this) {
9088            mProcessObservers.register(observer);
9089        }
9090    }
9091
9092    @Override
9093    public void unregisterProcessObserver(IProcessObserver observer) {
9094        synchronized (this) {
9095            mProcessObservers.unregister(observer);
9096        }
9097    }
9098
9099    @Override
9100    public boolean convertFromTranslucent(IBinder token) {
9101        final long origId = Binder.clearCallingIdentity();
9102        try {
9103            synchronized (this) {
9104                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9105                if (r == null) {
9106                    return false;
9107                }
9108                if (r.changeWindowTranslucency(true)) {
9109                    mWindowManager.setAppFullscreen(token, true);
9110                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9111                    return true;
9112                }
9113                return false;
9114            }
9115        } finally {
9116            Binder.restoreCallingIdentity(origId);
9117        }
9118    }
9119
9120    @Override
9121    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9122        final long origId = Binder.clearCallingIdentity();
9123        try {
9124            synchronized (this) {
9125                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9126                if (r == null) {
9127                    return false;
9128                }
9129                if (r.changeWindowTranslucency(false)) {
9130                    r.task.stack.convertToTranslucent(r, options);
9131                    mWindowManager.setAppFullscreen(token, false);
9132                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9133                    return true;
9134                }
9135                return false;
9136            }
9137        } finally {
9138            Binder.restoreCallingIdentity(origId);
9139        }
9140    }
9141
9142    @Override
9143    public ActivityOptions getActivityOptions(IBinder token) {
9144        final long origId = Binder.clearCallingIdentity();
9145        try {
9146            synchronized (this) {
9147                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9148                if (r != null) {
9149                    final ActivityOptions activityOptions = r.pendingOptions;
9150                    r.pendingOptions = null;
9151                    return activityOptions;
9152                }
9153                return null;
9154            }
9155        } finally {
9156            Binder.restoreCallingIdentity(origId);
9157        }
9158    }
9159
9160    @Override
9161    public void setImmersive(IBinder token, boolean immersive) {
9162        synchronized(this) {
9163            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9164            if (r == null) {
9165                throw new IllegalArgumentException();
9166            }
9167            r.immersive = immersive;
9168
9169            // update associated state if we're frontmost
9170            if (r == mFocusedActivity) {
9171                if (DEBUG_IMMERSIVE) {
9172                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9173                }
9174                applyUpdateLockStateLocked(r);
9175            }
9176        }
9177    }
9178
9179    @Override
9180    public boolean isImmersive(IBinder token) {
9181        synchronized (this) {
9182            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9183            if (r == null) {
9184                throw new IllegalArgumentException();
9185            }
9186            return r.immersive;
9187        }
9188    }
9189
9190    public boolean isTopActivityImmersive() {
9191        enforceNotIsolatedCaller("startActivity");
9192        synchronized (this) {
9193            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9194            return (r != null) ? r.immersive : false;
9195        }
9196    }
9197
9198    public final void enterSafeMode() {
9199        synchronized(this) {
9200            // It only makes sense to do this before the system is ready
9201            // and started launching other packages.
9202            if (!mSystemReady) {
9203                try {
9204                    AppGlobals.getPackageManager().enterSafeMode();
9205                } catch (RemoteException e) {
9206                }
9207            }
9208
9209            mSafeMode = true;
9210        }
9211    }
9212
9213    public final void showSafeModeOverlay() {
9214        View v = LayoutInflater.from(mContext).inflate(
9215                com.android.internal.R.layout.safe_mode, null);
9216        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9217        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9218        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9219        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9220        lp.gravity = Gravity.BOTTOM | Gravity.START;
9221        lp.format = v.getBackground().getOpacity();
9222        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9223                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9224        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9225        ((WindowManager)mContext.getSystemService(
9226                Context.WINDOW_SERVICE)).addView(v, lp);
9227    }
9228
9229    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9230        if (!(sender instanceof PendingIntentRecord)) {
9231            return;
9232        }
9233        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9234        synchronized (stats) {
9235            if (mBatteryStatsService.isOnBattery()) {
9236                mBatteryStatsService.enforceCallingPermission();
9237                PendingIntentRecord rec = (PendingIntentRecord)sender;
9238                int MY_UID = Binder.getCallingUid();
9239                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9240                BatteryStatsImpl.Uid.Pkg pkg =
9241                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9242                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9243                pkg.incWakeupsLocked();
9244            }
9245        }
9246    }
9247
9248    public boolean killPids(int[] pids, String pReason, boolean secure) {
9249        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9250            throw new SecurityException("killPids only available to the system");
9251        }
9252        String reason = (pReason == null) ? "Unknown" : pReason;
9253        // XXX Note: don't acquire main activity lock here, because the window
9254        // manager calls in with its locks held.
9255
9256        boolean killed = false;
9257        synchronized (mPidsSelfLocked) {
9258            int[] types = new int[pids.length];
9259            int worstType = 0;
9260            for (int i=0; i<pids.length; i++) {
9261                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9262                if (proc != null) {
9263                    int type = proc.setAdj;
9264                    types[i] = type;
9265                    if (type > worstType) {
9266                        worstType = type;
9267                    }
9268                }
9269            }
9270
9271            // If the worst oom_adj is somewhere in the cached proc LRU range,
9272            // then constrain it so we will kill all cached procs.
9273            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9274                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9275                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9276            }
9277
9278            // If this is not a secure call, don't let it kill processes that
9279            // are important.
9280            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9281                worstType = ProcessList.SERVICE_ADJ;
9282            }
9283
9284            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9285            for (int i=0; i<pids.length; i++) {
9286                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9287                if (proc == null) {
9288                    continue;
9289                }
9290                int adj = proc.setAdj;
9291                if (adj >= worstType && !proc.killedByAm) {
9292                    killUnneededProcessLocked(proc, reason);
9293                    killed = true;
9294                }
9295            }
9296        }
9297        return killed;
9298    }
9299
9300    @Override
9301    public void killUid(int uid, String reason) {
9302        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9303            throw new SecurityException("killUid only available to the system");
9304        }
9305        synchronized (this) {
9306            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9307                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9308                    reason != null ? reason : "kill uid");
9309        }
9310    }
9311
9312    @Override
9313    public boolean killProcessesBelowForeground(String reason) {
9314        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9315            throw new SecurityException("killProcessesBelowForeground() only available to system");
9316        }
9317
9318        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9319    }
9320
9321    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9322        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9323            throw new SecurityException("killProcessesBelowAdj() only available to system");
9324        }
9325
9326        boolean killed = false;
9327        synchronized (mPidsSelfLocked) {
9328            final int size = mPidsSelfLocked.size();
9329            for (int i = 0; i < size; i++) {
9330                final int pid = mPidsSelfLocked.keyAt(i);
9331                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9332                if (proc == null) continue;
9333
9334                final int adj = proc.setAdj;
9335                if (adj > belowAdj && !proc.killedByAm) {
9336                    killUnneededProcessLocked(proc, reason);
9337                    killed = true;
9338                }
9339            }
9340        }
9341        return killed;
9342    }
9343
9344    @Override
9345    public void hang(final IBinder who, boolean allowRestart) {
9346        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9347                != PackageManager.PERMISSION_GRANTED) {
9348            throw new SecurityException("Requires permission "
9349                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9350        }
9351
9352        final IBinder.DeathRecipient death = new DeathRecipient() {
9353            @Override
9354            public void binderDied() {
9355                synchronized (this) {
9356                    notifyAll();
9357                }
9358            }
9359        };
9360
9361        try {
9362            who.linkToDeath(death, 0);
9363        } catch (RemoteException e) {
9364            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9365            return;
9366        }
9367
9368        synchronized (this) {
9369            Watchdog.getInstance().setAllowRestart(allowRestart);
9370            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9371            synchronized (death) {
9372                while (who.isBinderAlive()) {
9373                    try {
9374                        death.wait();
9375                    } catch (InterruptedException e) {
9376                    }
9377                }
9378            }
9379            Watchdog.getInstance().setAllowRestart(true);
9380        }
9381    }
9382
9383    @Override
9384    public void restart() {
9385        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9386                != PackageManager.PERMISSION_GRANTED) {
9387            throw new SecurityException("Requires permission "
9388                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9389        }
9390
9391        Log.i(TAG, "Sending shutdown broadcast...");
9392
9393        BroadcastReceiver br = new BroadcastReceiver() {
9394            @Override public void onReceive(Context context, Intent intent) {
9395                // Now the broadcast is done, finish up the low-level shutdown.
9396                Log.i(TAG, "Shutting down activity manager...");
9397                shutdown(10000);
9398                Log.i(TAG, "Shutdown complete, restarting!");
9399                Process.killProcess(Process.myPid());
9400                System.exit(10);
9401            }
9402        };
9403
9404        // First send the high-level shut down broadcast.
9405        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9406        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9407        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9408        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9409        mContext.sendOrderedBroadcastAsUser(intent,
9410                UserHandle.ALL, null, br, mHandler, 0, null, null);
9411        */
9412        br.onReceive(mContext, intent);
9413    }
9414
9415    private long getLowRamTimeSinceIdle(long now) {
9416        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9417    }
9418
9419    @Override
9420    public void performIdleMaintenance() {
9421        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9422                != PackageManager.PERMISSION_GRANTED) {
9423            throw new SecurityException("Requires permission "
9424                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9425        }
9426
9427        synchronized (this) {
9428            final long now = SystemClock.uptimeMillis();
9429            final long timeSinceLastIdle = now - mLastIdleTime;
9430            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9431            mLastIdleTime = now;
9432            mLowRamTimeSinceLastIdle = 0;
9433            if (mLowRamStartTime != 0) {
9434                mLowRamStartTime = now;
9435            }
9436
9437            StringBuilder sb = new StringBuilder(128);
9438            sb.append("Idle maintenance over ");
9439            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9440            sb.append(" low RAM for ");
9441            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9442            Slog.i(TAG, sb.toString());
9443
9444            // If at least 1/3 of our time since the last idle period has been spent
9445            // with RAM low, then we want to kill processes.
9446            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9447
9448            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9449                ProcessRecord proc = mLruProcesses.get(i);
9450                if (proc.notCachedSinceIdle) {
9451                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9452                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9453                        if (doKilling && proc.initialIdlePss != 0
9454                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9455                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9456                                    + " from " + proc.initialIdlePss + ")");
9457                        }
9458                    }
9459                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9460                    proc.notCachedSinceIdle = true;
9461                    proc.initialIdlePss = 0;
9462                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9463                            isSleeping(), now);
9464                }
9465            }
9466
9467            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9468            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9469        }
9470    }
9471
9472    private void retrieveSettings() {
9473        final ContentResolver resolver = mContext.getContentResolver();
9474        String debugApp = Settings.Global.getString(
9475            resolver, Settings.Global.DEBUG_APP);
9476        boolean waitForDebugger = Settings.Global.getInt(
9477            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9478        boolean alwaysFinishActivities = Settings.Global.getInt(
9479            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9480        boolean forceRtl = Settings.Global.getInt(
9481                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9482        // Transfer any global setting for forcing RTL layout, into a System Property
9483        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9484
9485        Configuration configuration = new Configuration();
9486        Settings.System.getConfiguration(resolver, configuration);
9487        if (forceRtl) {
9488            // This will take care of setting the correct layout direction flags
9489            configuration.setLayoutDirection(configuration.locale);
9490        }
9491
9492        synchronized (this) {
9493            mDebugApp = mOrigDebugApp = debugApp;
9494            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9495            mAlwaysFinishActivities = alwaysFinishActivities;
9496            // This happens before any activities are started, so we can
9497            // change mConfiguration in-place.
9498            updateConfigurationLocked(configuration, null, false, true);
9499            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9500        }
9501    }
9502
9503    public boolean testIsSystemReady() {
9504        // no need to synchronize(this) just to read & return the value
9505        return mSystemReady;
9506    }
9507
9508    private static File getCalledPreBootReceiversFile() {
9509        File dataDir = Environment.getDataDirectory();
9510        File systemDir = new File(dataDir, "system");
9511        File fname = new File(systemDir, "called_pre_boots.dat");
9512        return fname;
9513    }
9514
9515    static final int LAST_DONE_VERSION = 10000;
9516
9517    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9518        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9519        File file = getCalledPreBootReceiversFile();
9520        FileInputStream fis = null;
9521        try {
9522            fis = new FileInputStream(file);
9523            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9524            int fvers = dis.readInt();
9525            if (fvers == LAST_DONE_VERSION) {
9526                String vers = dis.readUTF();
9527                String codename = dis.readUTF();
9528                String build = dis.readUTF();
9529                if (android.os.Build.VERSION.RELEASE.equals(vers)
9530                        && android.os.Build.VERSION.CODENAME.equals(codename)
9531                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9532                    int num = dis.readInt();
9533                    while (num > 0) {
9534                        num--;
9535                        String pkg = dis.readUTF();
9536                        String cls = dis.readUTF();
9537                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9538                    }
9539                }
9540            }
9541        } catch (FileNotFoundException e) {
9542        } catch (IOException e) {
9543            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9544        } finally {
9545            if (fis != null) {
9546                try {
9547                    fis.close();
9548                } catch (IOException e) {
9549                }
9550            }
9551        }
9552        return lastDoneReceivers;
9553    }
9554
9555    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9556        File file = getCalledPreBootReceiversFile();
9557        FileOutputStream fos = null;
9558        DataOutputStream dos = null;
9559        try {
9560            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9561            fos = new FileOutputStream(file);
9562            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9563            dos.writeInt(LAST_DONE_VERSION);
9564            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9565            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9566            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9567            dos.writeInt(list.size());
9568            for (int i=0; i<list.size(); i++) {
9569                dos.writeUTF(list.get(i).getPackageName());
9570                dos.writeUTF(list.get(i).getClassName());
9571            }
9572        } catch (IOException e) {
9573            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9574            file.delete();
9575        } finally {
9576            FileUtils.sync(fos);
9577            if (dos != null) {
9578                try {
9579                    dos.close();
9580                } catch (IOException e) {
9581                    // TODO Auto-generated catch block
9582                    e.printStackTrace();
9583                }
9584            }
9585        }
9586    }
9587
9588    public void systemReady(final Runnable goingCallback) {
9589        synchronized(this) {
9590            if (mSystemReady) {
9591                if (goingCallback != null) goingCallback.run();
9592                return;
9593            }
9594
9595            if (mRecentTasks == null) {
9596                mRecentTasks = mTaskPersister.restoreTasksLocked();
9597                if (!mRecentTasks.isEmpty()) {
9598                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9599                }
9600                mTaskPersister.startPersisting();
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.EXTRA_PROXY_INFO);
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