ActivityManagerService.java revision f1939901d2ed0480069f0b23be64f122fce93995
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49
50import android.util.SparseIntArray;
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225    private static final String USER_DATA_DIR = "/data/user/";
226    static final String TAG = "ActivityManager";
227    static final String TAG_MU = "ActivityManagerServiceMU";
228    static final boolean DEBUG = false;
229    static final boolean localLOGV = DEBUG;
230    static final boolean DEBUG_BACKUP = localLOGV || false;
231    static final boolean DEBUG_BROADCAST = localLOGV || false;
232    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
233    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
234    static final boolean DEBUG_CLEANUP = localLOGV || false;
235    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
236    static final boolean DEBUG_FOCUS = false;
237    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
238    static final boolean DEBUG_MU = localLOGV || false;
239    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
240    static final boolean DEBUG_LRU = localLOGV || false;
241    static final boolean DEBUG_PAUSE = localLOGV || false;
242    static final boolean DEBUG_POWER = localLOGV || false;
243    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
244    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
245    static final boolean DEBUG_PROCESSES = localLOGV || false;
246    static final boolean DEBUG_PROVIDER = localLOGV || false;
247    static final boolean DEBUG_RESULTS = localLOGV || false;
248    static final boolean DEBUG_SERVICE = localLOGV || false;
249    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
250    static final boolean DEBUG_STACK = localLOGV || false;
251    static final boolean DEBUG_SWITCH = localLOGV || false;
252    static final boolean DEBUG_TASKS = localLOGV || false;
253    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
254    static final boolean DEBUG_TRANSITION = localLOGV || false;
255    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
256    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
257    static final boolean DEBUG_VISBILITY = localLOGV || false;
258    static final boolean DEBUG_PSS = localLOGV || false;
259    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
260    static final boolean VALIDATE_TOKENS = false;
261    static final boolean SHOW_ACTIVITY_START_TIME = true;
262
263    // Control over CPU and battery monitoring.
264    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
265    static final boolean MONITOR_CPU_USAGE = true;
266    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
267    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
268    static final boolean MONITOR_THREAD_CPU_USAGE = false;
269
270    // The flags that are set for all calls we make to the package manager.
271    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
272
273    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
274
275    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
276
277    // Maximum number of recent tasks that we can remember.
278    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
279
280    // Maximum number recent bitmaps to keep in memory.
281    static final int MAX_RECENT_BITMAPS = 5;
282
283    // Amount of time after a call to stopAppSwitches() during which we will
284    // prevent further untrusted switches from happening.
285    static final long APP_SWITCH_DELAY_TIME = 5*1000;
286
287    // How long we wait for a launched process to attach to the activity manager
288    // before we decide it's never going to come up for real.
289    static final int PROC_START_TIMEOUT = 10*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real, when the process was
293    // started with a wrapper for instrumentation (such as Valgrind) because it
294    // could take much longer than usual.
295    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
296
297    // How long to wait after going idle before forcing apps to GC.
298    static final int GC_TIMEOUT = 5*1000;
299
300    // The minimum amount of time between successive GC requests for a process.
301    static final int GC_MIN_INTERVAL = 60*1000;
302
303    // The minimum amount of time between successive PSS requests for a process.
304    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
305
306    // The minimum amount of time between successive PSS requests for a process
307    // when the request is due to the memory state being lowered.
308    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
309
310    // The rate at which we check for apps using excessive power -- 15 mins.
311    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
312
313    // The minimum sample duration we will allow before deciding we have
314    // enough data on wake locks to start killing things.
315    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on CPU usage to start killing things.
319    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // How long we allow a receiver to run before giving up on it.
322    static final int BROADCAST_FG_TIMEOUT = 10*1000;
323    static final int BROADCAST_BG_TIMEOUT = 60*1000;
324
325    // How long we wait until we timeout on key dispatching.
326    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
327
328    // How long we wait until we timeout on key dispatching during instrumentation.
329    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
330
331    // Amount of time we wait for observers to handle a user switch before
332    // giving up on them and unfreezing the screen.
333    static final int USER_SWITCH_TIMEOUT = 2*1000;
334
335    // Maximum number of users we allow to be running at a time.
336    static final int MAX_RUNNING_USERS = 3;
337
338    // How long to wait in getAssistContextExtras for the activity and foreground services
339    // to respond with the result.
340    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
341
342    // Maximum number of persisted Uri grants a package is allowed
343    static final int MAX_PERSISTED_URI_GRANTS = 128;
344
345    static final int MY_PID = Process.myPid();
346
347    static final String[] EMPTY_STRING_ARRAY = new String[0];
348
349    // How many bytes to write into the dropbox log before truncating
350    static final int DROPBOX_MAX_SIZE = 256 * 1024;
351
352    // Access modes for handleIncomingUser.
353    static final int ALLOW_NON_FULL = 0;
354    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
355    static final int ALLOW_FULL_ONLY = 2;
356
357    /** All system services */
358    SystemServiceManager mSystemServiceManager;
359
360    /** Run all ActivityStacks through this */
361    ActivityStackSupervisor mStackSupervisor;
362
363    public IntentFirewall mIntentFirewall;
364
365    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
366    // default actuion automatically.  Important for devices without direct input
367    // devices.
368    private boolean mShowDialogs = true;
369
370    BroadcastQueue mFgBroadcastQueue;
371    BroadcastQueue mBgBroadcastQueue;
372    // Convenient for easy iteration over the queues. Foreground is first
373    // so that dispatch of foreground broadcasts gets precedence.
374    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
375
376    BroadcastQueue broadcastQueueForIntent(Intent intent) {
377        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
378        if (DEBUG_BACKGROUND_BROADCAST) {
379            Slog.i(TAG, "Broadcast intent " + intent + " on "
380                    + (isFg ? "foreground" : "background")
381                    + " queue");
382        }
383        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
384    }
385
386    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
387        for (BroadcastQueue queue : mBroadcastQueues) {
388            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
389            if (r != null) {
390                return r;
391            }
392        }
393        return null;
394    }
395
396    /**
397     * Activity we have told the window manager to have key focus.
398     */
399    ActivityRecord mFocusedActivity = null;
400
401    /**
402     * List of intents that were used to start the most recent tasks.
403     */
404    ArrayList<TaskRecord> mRecentTasks;
405    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
406
407    public class PendingAssistExtras extends Binder implements Runnable {
408        public final ActivityRecord activity;
409        public boolean haveResult = false;
410        public Bundle result = null;
411        public PendingAssistExtras(ActivityRecord _activity) {
412            activity = _activity;
413        }
414        @Override
415        public void run() {
416            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
417            synchronized (this) {
418                haveResult = true;
419                notifyAll();
420            }
421        }
422    }
423
424    final ArrayList<PendingAssistExtras> mPendingAssistExtras
425            = new ArrayList<PendingAssistExtras>();
426
427    /**
428     * Process management.
429     */
430    final ProcessList mProcessList = new ProcessList();
431
432    /**
433     * All of the applications we currently have running organized by name.
434     * The keys are strings of the application package name (as
435     * returned by the package manager), and the keys are ApplicationRecord
436     * objects.
437     */
438    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
439
440    /**
441     * Tracking long-term execution of processes to look for abuse and other
442     * bad app behavior.
443     */
444    final ProcessStatsService mProcessStats;
445
446    /**
447     * The currently running isolated processes.
448     */
449    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
450
451    /**
452     * Counter for assigning isolated process uids, to avoid frequently reusing the
453     * same ones.
454     */
455    int mNextIsolatedProcessUid = 0;
456
457    /**
458     * The currently running heavy-weight process, if any.
459     */
460    ProcessRecord mHeavyWeightProcess = null;
461
462    /**
463     * The last time that various processes have crashed.
464     */
465    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
466
467    /**
468     * Information about a process that is currently marked as bad.
469     */
470    static final class BadProcessInfo {
471        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
472            this.time = time;
473            this.shortMsg = shortMsg;
474            this.longMsg = longMsg;
475            this.stack = stack;
476        }
477
478        final long time;
479        final String shortMsg;
480        final String longMsg;
481        final String stack;
482    }
483
484    /**
485     * Set of applications that we consider to be bad, and will reject
486     * incoming broadcasts from (which the user has no control over).
487     * Processes are added to this set when they have crashed twice within
488     * a minimum amount of time; they are removed from it when they are
489     * later restarted (hopefully due to some user action).  The value is the
490     * time it was added to the list.
491     */
492    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
493
494    /**
495     * All of the processes we currently have running organized by pid.
496     * The keys are the pid running the application.
497     *
498     * <p>NOTE: This object is protected by its own lock, NOT the global
499     * activity manager lock!
500     */
501    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
502
503    /**
504     * All of the processes that have been forced to be foreground.  The key
505     * is the pid of the caller who requested it (we hold a death
506     * link on it).
507     */
508    abstract class ForegroundToken implements IBinder.DeathRecipient {
509        int pid;
510        IBinder token;
511    }
512    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
513
514    /**
515     * List of records for processes that someone had tried to start before the
516     * system was ready.  We don't start them at that point, but ensure they
517     * are started by the time booting is complete.
518     */
519    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
520
521    /**
522     * List of persistent applications that are in the process
523     * of being started.
524     */
525    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
526
527    /**
528     * Processes that are being forcibly torn down.
529     */
530    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * List of running applications, sorted by recent usage.
534     * The first entry in the list is the least recently used.
535     */
536    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * Where in mLruProcesses that the processes hosting activities start.
540     */
541    int mLruProcessActivityStart = 0;
542
543    /**
544     * Where in mLruProcesses that the processes hosting services start.
545     * This is after (lower index) than mLruProcessesActivityStart.
546     */
547    int mLruProcessServiceStart = 0;
548
549    /**
550     * List of processes that should gc as soon as things are idle.
551     */
552    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
553
554    /**
555     * Processes we want to collect PSS data from.
556     */
557    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
558
559    /**
560     * Last time we requested PSS data of all processes.
561     */
562    long mLastFullPssTime = SystemClock.uptimeMillis();
563
564    /**
565     * If set, the next time we collect PSS data we should do a full collection
566     * with data from native processes and the kernel.
567     */
568    boolean mFullPssPending = false;
569
570    /**
571     * This is the process holding what we currently consider to be
572     * the "home" activity.
573     */
574    ProcessRecord mHomeProcess;
575
576    /**
577     * This is the process holding the activity the user last visited that
578     * is in a different process from the one they are currently in.
579     */
580    ProcessRecord mPreviousProcess;
581
582    /**
583     * The time at which the previous process was last visible.
584     */
585    long mPreviousProcessVisibleTime;
586
587    /**
588     * Which uses have been started, so are allowed to run code.
589     */
590    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
591
592    /**
593     * LRU list of history of current users.  Most recently current is at the end.
594     */
595    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
596
597    /**
598     * Constant array of the users that are currently started.
599     */
600    int[] mStartedUserArray = new int[] { 0 };
601
602    /**
603     * Registered observers of the user switching mechanics.
604     */
605    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
606            = new RemoteCallbackList<IUserSwitchObserver>();
607
608    /**
609     * Currently active user switch.
610     */
611    Object mCurUserSwitchCallback;
612
613    /**
614     * Packages that the user has asked to have run in screen size
615     * compatibility mode instead of filling the screen.
616     */
617    final CompatModePackages mCompatModePackages;
618
619    /**
620     * Set of IntentSenderRecord objects that are currently active.
621     */
622    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
623            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
624
625    /**
626     * Fingerprints (hashCode()) of stack traces that we've
627     * already logged DropBox entries for.  Guarded by itself.  If
628     * something (rogue user app) forces this over
629     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
630     */
631    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
632    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
633
634    /**
635     * Strict Mode background batched logging state.
636     *
637     * The string buffer is guarded by itself, and its lock is also
638     * used to determine if another batched write is already
639     * in-flight.
640     */
641    private final StringBuilder mStrictModeBuffer = new StringBuilder();
642
643    /**
644     * Keeps track of all IIntentReceivers that have been registered for
645     * broadcasts.  Hash keys are the receiver IBinder, hash value is
646     * a ReceiverList.
647     */
648    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
649            new HashMap<IBinder, ReceiverList>();
650
651    /**
652     * Resolver for broadcast intents to registered receivers.
653     * Holds BroadcastFilter (subclass of IntentFilter).
654     */
655    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
656            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
657        @Override
658        protected boolean allowFilterResult(
659                BroadcastFilter filter, List<BroadcastFilter> dest) {
660            IBinder target = filter.receiverList.receiver.asBinder();
661            for (int i=dest.size()-1; i>=0; i--) {
662                if (dest.get(i).receiverList.receiver.asBinder() == target) {
663                    return false;
664                }
665            }
666            return true;
667        }
668
669        @Override
670        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
671            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
672                    || userId == filter.owningUserId) {
673                return super.newResult(filter, match, userId);
674            }
675            return null;
676        }
677
678        @Override
679        protected BroadcastFilter[] newArray(int size) {
680            return new BroadcastFilter[size];
681        }
682
683        @Override
684        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
685            return packageName.equals(filter.packageName);
686        }
687    };
688
689    /**
690     * State of all active sticky broadcasts per user.  Keys are the action of the
691     * sticky Intent, values are an ArrayList of all broadcasted intents with
692     * that action (which should usually be one).  The SparseArray is keyed
693     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
694     * for stickies that are sent to all users.
695     */
696    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
697            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
698
699    final ActiveServices mServices;
700
701    /**
702     * Backup/restore process management
703     */
704    String mBackupAppName = null;
705    BackupRecord mBackupTarget = null;
706
707    final ProviderMap mProviderMap;
708
709    /**
710     * List of content providers who have clients waiting for them.  The
711     * application is currently being launched and the provider will be
712     * removed from this list once it is published.
713     */
714    final ArrayList<ContentProviderRecord> mLaunchingProviders
715            = new ArrayList<ContentProviderRecord>();
716
717    /**
718     * File storing persisted {@link #mGrantedUriPermissions}.
719     */
720    private final AtomicFile mGrantFile;
721
722    /** XML constants used in {@link #mGrantFile} */
723    private static final String TAG_URI_GRANTS = "uri-grants";
724    private static final String TAG_URI_GRANT = "uri-grant";
725    private static final String ATTR_USER_HANDLE = "userHandle";
726    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
727    private static final String ATTR_TARGET_USER_ID = "targetUserId";
728    private static final String ATTR_SOURCE_PKG = "sourcePkg";
729    private static final String ATTR_TARGET_PKG = "targetPkg";
730    private static final String ATTR_URI = "uri";
731    private static final String ATTR_MODE_FLAGS = "modeFlags";
732    private static final String ATTR_CREATED_TIME = "createdTime";
733    private static final String ATTR_PREFIX = "prefix";
734
735    /**
736     * Global set of specific {@link Uri} permissions that have been granted.
737     * This optimized lookup structure maps from {@link UriPermission#targetUid}
738     * to {@link UriPermission#uri} to {@link UriPermission}.
739     */
740    @GuardedBy("this")
741    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
742            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
743
744    public static class GrantUri {
745        public final int sourceUserId;
746        public final Uri uri;
747        public boolean prefix;
748
749        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
750            this.sourceUserId = sourceUserId;
751            this.uri = uri;
752            this.prefix = prefix;
753        }
754
755        @Override
756        public int hashCode() {
757            return toString().hashCode();
758        }
759
760        @Override
761        public boolean equals(Object o) {
762            if (o instanceof GrantUri) {
763                GrantUri other = (GrantUri) o;
764                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
765                        && prefix == other.prefix;
766            }
767            return false;
768        }
769
770        @Override
771        public String toString() {
772            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
773            if (prefix) result += " [prefix]";
774            return result;
775        }
776
777        public String toSafeString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
784            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
785                    ContentProvider.getUriWithoutUserId(uri), false);
786        }
787    }
788
789    CoreSettingsObserver mCoreSettingsObserver;
790
791    /**
792     * Thread-local storage used to carry caller permissions over through
793     * indirect content-provider access.
794     */
795    private class Identity {
796        public int pid;
797        public int uid;
798
799        Identity(int _pid, int _uid) {
800            pid = _pid;
801            uid = _uid;
802        }
803    }
804
805    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
806
807    /**
808     * All information we have collected about the runtime performance of
809     * any user id that can impact battery performance.
810     */
811    final BatteryStatsService mBatteryStatsService;
812
813    /**
814     * Information about component usage
815     */
816    UsageStatsManagerInternal mUsageStatsService;
817
818    /**
819     * Information about and control over application operations
820     */
821    final AppOpsService mAppOpsService;
822
823    /**
824     * Save recent tasks information across reboots.
825     */
826    final TaskPersister mTaskPersister;
827
828    /**
829     * Current configuration information.  HistoryRecord objects are given
830     * a reference to this object to indicate which configuration they are
831     * currently running in, so this object must be kept immutable.
832     */
833    Configuration mConfiguration = new Configuration();
834
835    /**
836     * Current sequencing integer of the configuration, for skipping old
837     * configurations.
838     */
839    int mConfigurationSeq = 0;
840
841    /**
842     * Hardware-reported OpenGLES version.
843     */
844    final int GL_ES_VERSION;
845
846    /**
847     * List of initialization arguments to pass to all processes when binding applications to them.
848     * For example, references to the commonly used services.
849     */
850    HashMap<String, IBinder> mAppBindArgs;
851
852    /**
853     * Temporary to avoid allocations.  Protected by main lock.
854     */
855    final StringBuilder mStringBuilder = new StringBuilder(256);
856
857    /**
858     * Used to control how we initialize the service.
859     */
860    ComponentName mTopComponent;
861    String mTopAction = Intent.ACTION_MAIN;
862    String mTopData;
863    boolean mProcessesReady = false;
864    boolean mSystemReady = false;
865    boolean mBooting = false;
866    boolean mWaitingUpdate = false;
867    boolean mDidUpdate = false;
868    boolean mOnBattery = false;
869    boolean mLaunchWarningShown = false;
870
871    Context mContext;
872
873    int mFactoryTest;
874
875    boolean mCheckedForSetup;
876
877    /**
878     * The time at which we will allow normal application switches again,
879     * after a call to {@link #stopAppSwitches()}.
880     */
881    long mAppSwitchesAllowedTime;
882
883    /**
884     * This is set to true after the first switch after mAppSwitchesAllowedTime
885     * is set; any switches after that will clear the time.
886     */
887    boolean mDidAppSwitch;
888
889    /**
890     * Last time (in realtime) at which we checked for power usage.
891     */
892    long mLastPowerCheckRealtime;
893
894    /**
895     * Last time (in uptime) at which we checked for power usage.
896     */
897    long mLastPowerCheckUptime;
898
899    /**
900     * Set while we are wanting to sleep, to prevent any
901     * activities from being started/resumed.
902     */
903    private boolean mSleeping = false;
904
905    /**
906     * Set while we are running a voice interaction.  This overrides
907     * sleeping while it is active.
908     */
909    private boolean mRunningVoice = false;
910
911    /**
912     * State of external calls telling us if the device is asleep.
913     */
914    private boolean mWentToSleep = false;
915
916    /**
917     * State of external call telling us if the lock screen is shown.
918     */
919    private boolean mLockScreenShown = false;
920
921    /**
922     * Set if we are shutting down the system, similar to sleeping.
923     */
924    boolean mShuttingDown = false;
925
926    /**
927     * Current sequence id for oom_adj computation traversal.
928     */
929    int mAdjSeq = 0;
930
931    /**
932     * Current sequence id for process LRU updating.
933     */
934    int mLruSeq = 0;
935
936    /**
937     * Keep track of the non-cached/empty process we last found, to help
938     * determine how to distribute cached/empty processes next time.
939     */
940    int mNumNonCachedProcs = 0;
941
942    /**
943     * Keep track of the number of cached hidden procs, to balance oom adj
944     * distribution between those and empty procs.
945     */
946    int mNumCachedHiddenProcs = 0;
947
948    /**
949     * Keep track of the number of service processes we last found, to
950     * determine on the next iteration which should be B services.
951     */
952    int mNumServiceProcs = 0;
953    int mNewNumAServiceProcs = 0;
954    int mNewNumServiceProcs = 0;
955
956    /**
957     * Allow the current computed overall memory level of the system to go down?
958     * This is set to false when we are killing processes for reasons other than
959     * memory management, so that the now smaller process list will not be taken as
960     * an indication that memory is tighter.
961     */
962    boolean mAllowLowerMemLevel = false;
963
964    /**
965     * The last computed memory level, for holding when we are in a state that
966     * processes are going away for other reasons.
967     */
968    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
969
970    /**
971     * The last total number of process we have, to determine if changes actually look
972     * like a shrinking number of process due to lower RAM.
973     */
974    int mLastNumProcesses;
975
976    /**
977     * The uptime of the last time we performed idle maintenance.
978     */
979    long mLastIdleTime = SystemClock.uptimeMillis();
980
981    /**
982     * Total time spent with RAM that has been added in the past since the last idle time.
983     */
984    long mLowRamTimeSinceLastIdle = 0;
985
986    /**
987     * If RAM is currently low, when that horrible situation started.
988     */
989    long mLowRamStartTime = 0;
990
991    /**
992     * For reporting to battery stats the current top application.
993     */
994    private String mCurResumedPackage = null;
995    private int mCurResumedUid = -1;
996
997    /**
998     * For reporting to battery stats the apps currently running foreground
999     * service.  The ProcessMap is package/uid tuples; each of these contain
1000     * an array of the currently foreground processes.
1001     */
1002    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1003            = new ProcessMap<ArrayList<ProcessRecord>>();
1004
1005    /**
1006     * This is set if we had to do a delayed dexopt of an app before launching
1007     * it, to increase the ANR timeouts in that case.
1008     */
1009    boolean mDidDexOpt;
1010
1011    /**
1012     * Set if the systemServer made a call to enterSafeMode.
1013     */
1014    boolean mSafeMode;
1015
1016    String mDebugApp = null;
1017    boolean mWaitForDebugger = false;
1018    boolean mDebugTransient = false;
1019    String mOrigDebugApp = null;
1020    boolean mOrigWaitForDebugger = false;
1021    boolean mAlwaysFinishActivities = false;
1022    IActivityController mController = null;
1023    String mProfileApp = null;
1024    ProcessRecord mProfileProc = null;
1025    String mProfileFile;
1026    ParcelFileDescriptor mProfileFd;
1027    int mProfileType = 0;
1028    boolean mAutoStopProfiler = false;
1029    String mOpenGlTraceApp = null;
1030
1031    static class ProcessChangeItem {
1032        static final int CHANGE_ACTIVITIES = 1<<0;
1033        static final int CHANGE_PROCESS_STATE = 1<<1;
1034        int changes;
1035        int uid;
1036        int pid;
1037        int processState;
1038        boolean foregroundActivities;
1039    }
1040
1041    final RemoteCallbackList<IProcessObserver> mProcessObservers
1042            = new RemoteCallbackList<IProcessObserver>();
1043    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1044
1045    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1046            = new ArrayList<ProcessChangeItem>();
1047    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1048            = new ArrayList<ProcessChangeItem>();
1049
1050    /**
1051     * Runtime CPU use collection thread.  This object's lock is used to
1052     * protect all related state.
1053     */
1054    final Thread mProcessCpuThread;
1055
1056    /**
1057     * Used to collect process stats when showing not responding dialog.
1058     * Protected by mProcessCpuThread.
1059     */
1060    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1061            MONITOR_THREAD_CPU_USAGE);
1062    final AtomicLong mLastCpuTime = new AtomicLong(0);
1063    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1064
1065    long mLastWriteTime = 0;
1066
1067    /**
1068     * Used to retain an update lock when the foreground activity is in
1069     * immersive mode.
1070     */
1071    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1072
1073    /**
1074     * Set to true after the system has finished booting.
1075     */
1076    boolean mBooted = false;
1077
1078    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1079    int mProcessLimitOverride = -1;
1080
1081    WindowManagerService mWindowManager;
1082
1083    final ActivityThread mSystemThread;
1084
1085    int mCurrentUserId = 0;
1086    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1087
1088    /**
1089     * Mapping from each known user ID to the profile group ID it is associated with.
1090     */
1091    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1092
1093    private UserManagerService mUserManager;
1094
1095    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1096        final ProcessRecord mApp;
1097        final int mPid;
1098        final IApplicationThread mAppThread;
1099
1100        AppDeathRecipient(ProcessRecord app, int pid,
1101                IApplicationThread thread) {
1102            if (localLOGV) Slog.v(
1103                TAG, "New death recipient " + this
1104                + " for thread " + thread.asBinder());
1105            mApp = app;
1106            mPid = pid;
1107            mAppThread = thread;
1108        }
1109
1110        @Override
1111        public void binderDied() {
1112            if (localLOGV) Slog.v(
1113                TAG, "Death received in " + this
1114                + " for thread " + mAppThread.asBinder());
1115            synchronized(ActivityManagerService.this) {
1116                appDiedLocked(mApp, mPid, mAppThread);
1117            }
1118        }
1119    }
1120
1121    static final int SHOW_ERROR_MSG = 1;
1122    static final int SHOW_NOT_RESPONDING_MSG = 2;
1123    static final int SHOW_FACTORY_ERROR_MSG = 3;
1124    static final int UPDATE_CONFIGURATION_MSG = 4;
1125    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1126    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1127    static final int SERVICE_TIMEOUT_MSG = 12;
1128    static final int UPDATE_TIME_ZONE = 13;
1129    static final int SHOW_UID_ERROR_MSG = 14;
1130    static final int IM_FEELING_LUCKY_MSG = 15;
1131    static final int PROC_START_TIMEOUT_MSG = 20;
1132    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1133    static final int KILL_APPLICATION_MSG = 22;
1134    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1135    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1136    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1137    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1138    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1139    static final int CLEAR_DNS_CACHE_MSG = 28;
1140    static final int UPDATE_HTTP_PROXY_MSG = 29;
1141    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1142    static final int DISPATCH_PROCESSES_CHANGED = 31;
1143    static final int DISPATCH_PROCESS_DIED = 32;
1144    static final int REPORT_MEM_USAGE_MSG = 33;
1145    static final int REPORT_USER_SWITCH_MSG = 34;
1146    static final int CONTINUE_USER_SWITCH_MSG = 35;
1147    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1148    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1149    static final int PERSIST_URI_GRANTS_MSG = 38;
1150    static final int REQUEST_ALL_PSS_MSG = 39;
1151    static final int START_PROFILES_MSG = 40;
1152    static final int UPDATE_TIME = 41;
1153    static final int SYSTEM_USER_START_MSG = 42;
1154    static final int SYSTEM_USER_CURRENT_MSG = 43;
1155
1156    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1157    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1158    static final int FIRST_COMPAT_MODE_MSG = 300;
1159    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1160
1161    AlertDialog mUidAlert;
1162    CompatModeDialog mCompatModeDialog;
1163    long mLastMemUsageReportTime = 0;
1164
1165    private LockToAppRequestDialog mLockToAppRequest;
1166
1167    /**
1168     * Flag whether the current user is a "monkey", i.e. whether
1169     * the UI is driven by a UI automation tool.
1170     */
1171    private boolean mUserIsMonkey;
1172
1173    /** Flag whether the device has a recents UI */
1174    final boolean mHasRecents;
1175
1176    final ServiceThread mHandlerThread;
1177    final MainHandler mHandler;
1178
1179    final class MainHandler extends Handler {
1180        public MainHandler(Looper looper) {
1181            super(looper, null, true);
1182        }
1183
1184        @Override
1185        public void handleMessage(Message msg) {
1186            switch (msg.what) {
1187            case SHOW_ERROR_MSG: {
1188                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1189                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1190                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1191                synchronized (ActivityManagerService.this) {
1192                    ProcessRecord proc = (ProcessRecord)data.get("app");
1193                    AppErrorResult res = (AppErrorResult) data.get("result");
1194                    if (proc != null && proc.crashDialog != null) {
1195                        Slog.e(TAG, "App already has crash dialog: " + proc);
1196                        if (res != null) {
1197                            res.set(0);
1198                        }
1199                        return;
1200                    }
1201                    if (!showBackground && UserHandle.getAppId(proc.uid)
1202                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1203                            && proc.pid != MY_PID) {
1204                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1205                        if (res != null) {
1206                            res.set(0);
1207                        }
1208                        return;
1209                    }
1210                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1211                        Dialog d = new AppErrorDialog(mContext,
1212                                ActivityManagerService.this, res, proc);
1213                        d.show();
1214                        proc.crashDialog = d;
1215                    } else {
1216                        // The device is asleep, so just pretend that the user
1217                        // saw a crash dialog and hit "force quit".
1218                        if (res != null) {
1219                            res.set(0);
1220                        }
1221                    }
1222                }
1223
1224                ensureBootCompleted();
1225            } break;
1226            case SHOW_NOT_RESPONDING_MSG: {
1227                synchronized (ActivityManagerService.this) {
1228                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1229                    ProcessRecord proc = (ProcessRecord)data.get("app");
1230                    if (proc != null && proc.anrDialog != null) {
1231                        Slog.e(TAG, "App already has anr dialog: " + proc);
1232                        return;
1233                    }
1234
1235                    Intent intent = new Intent("android.intent.action.ANR");
1236                    if (!mProcessesReady) {
1237                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1238                                | Intent.FLAG_RECEIVER_FOREGROUND);
1239                    }
1240                    broadcastIntentLocked(null, null, intent,
1241                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1242                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1243
1244                    if (mShowDialogs) {
1245                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1246                                mContext, proc, (ActivityRecord)data.get("activity"),
1247                                msg.arg1 != 0);
1248                        d.show();
1249                        proc.anrDialog = d;
1250                    } else {
1251                        // Just kill the app if there is no dialog to be shown.
1252                        killAppAtUsersRequest(proc, null);
1253                    }
1254                }
1255
1256                ensureBootCompleted();
1257            } break;
1258            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1259                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1260                synchronized (ActivityManagerService.this) {
1261                    ProcessRecord proc = (ProcessRecord) data.get("app");
1262                    if (proc == null) {
1263                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1264                        break;
1265                    }
1266                    if (proc.crashDialog != null) {
1267                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1268                        return;
1269                    }
1270                    AppErrorResult res = (AppErrorResult) data.get("result");
1271                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1272                        Dialog d = new StrictModeViolationDialog(mContext,
1273                                ActivityManagerService.this, res, proc);
1274                        d.show();
1275                        proc.crashDialog = d;
1276                    } else {
1277                        // The device is asleep, so just pretend that the user
1278                        // saw a crash dialog and hit "force quit".
1279                        res.set(0);
1280                    }
1281                }
1282                ensureBootCompleted();
1283            } break;
1284            case SHOW_FACTORY_ERROR_MSG: {
1285                Dialog d = new FactoryErrorDialog(
1286                    mContext, msg.getData().getCharSequence("msg"));
1287                d.show();
1288                ensureBootCompleted();
1289            } break;
1290            case UPDATE_CONFIGURATION_MSG: {
1291                final ContentResolver resolver = mContext.getContentResolver();
1292                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1293            } break;
1294            case GC_BACKGROUND_PROCESSES_MSG: {
1295                synchronized (ActivityManagerService.this) {
1296                    performAppGcsIfAppropriateLocked();
1297                }
1298            } break;
1299            case WAIT_FOR_DEBUGGER_MSG: {
1300                synchronized (ActivityManagerService.this) {
1301                    ProcessRecord app = (ProcessRecord)msg.obj;
1302                    if (msg.arg1 != 0) {
1303                        if (!app.waitedForDebugger) {
1304                            Dialog d = new AppWaitingForDebuggerDialog(
1305                                    ActivityManagerService.this,
1306                                    mContext, app);
1307                            app.waitDialog = d;
1308                            app.waitedForDebugger = true;
1309                            d.show();
1310                        }
1311                    } else {
1312                        if (app.waitDialog != null) {
1313                            app.waitDialog.dismiss();
1314                            app.waitDialog = null;
1315                        }
1316                    }
1317                }
1318            } break;
1319            case SERVICE_TIMEOUT_MSG: {
1320                if (mDidDexOpt) {
1321                    mDidDexOpt = false;
1322                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1323                    nmsg.obj = msg.obj;
1324                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1325                    return;
1326                }
1327                mServices.serviceTimeout((ProcessRecord)msg.obj);
1328            } break;
1329            case UPDATE_TIME_ZONE: {
1330                synchronized (ActivityManagerService.this) {
1331                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1332                        ProcessRecord r = mLruProcesses.get(i);
1333                        if (r.thread != null) {
1334                            try {
1335                                r.thread.updateTimeZone();
1336                            } catch (RemoteException ex) {
1337                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1338                            }
1339                        }
1340                    }
1341                }
1342            } break;
1343            case CLEAR_DNS_CACHE_MSG: {
1344                synchronized (ActivityManagerService.this) {
1345                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1346                        ProcessRecord r = mLruProcesses.get(i);
1347                        if (r.thread != null) {
1348                            try {
1349                                r.thread.clearDnsCache();
1350                            } catch (RemoteException ex) {
1351                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1352                            }
1353                        }
1354                    }
1355                }
1356            } break;
1357            case UPDATE_HTTP_PROXY_MSG: {
1358                ProxyInfo proxy = (ProxyInfo)msg.obj;
1359                String host = "";
1360                String port = "";
1361                String exclList = "";
1362                Uri pacFileUrl = Uri.EMPTY;
1363                if (proxy != null) {
1364                    host = proxy.getHost();
1365                    port = Integer.toString(proxy.getPort());
1366                    exclList = proxy.getExclusionListAsString();
1367                    pacFileUrl = proxy.getPacFileUrl();
1368                }
1369                synchronized (ActivityManagerService.this) {
1370                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1371                        ProcessRecord r = mLruProcesses.get(i);
1372                        if (r.thread != null) {
1373                            try {
1374                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1375                            } catch (RemoteException ex) {
1376                                Slog.w(TAG, "Failed to update http proxy for: " +
1377                                        r.info.processName);
1378                            }
1379                        }
1380                    }
1381                }
1382            } break;
1383            case SHOW_UID_ERROR_MSG: {
1384                String title = "System UIDs Inconsistent";
1385                String text = "UIDs on the system are inconsistent, you need to wipe your"
1386                        + " data partition or your device will be unstable.";
1387                Log.e(TAG, title + ": " + text);
1388                if (mShowDialogs) {
1389                    // XXX This is a temporary dialog, no need to localize.
1390                    AlertDialog d = new BaseErrorDialog(mContext);
1391                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1392                    d.setCancelable(false);
1393                    d.setTitle(title);
1394                    d.setMessage(text);
1395                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1396                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1397                    mUidAlert = d;
1398                    d.show();
1399                }
1400            } break;
1401            case IM_FEELING_LUCKY_MSG: {
1402                if (mUidAlert != null) {
1403                    mUidAlert.dismiss();
1404                    mUidAlert = null;
1405                }
1406            } break;
1407            case PROC_START_TIMEOUT_MSG: {
1408                if (mDidDexOpt) {
1409                    mDidDexOpt = false;
1410                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1411                    nmsg.obj = msg.obj;
1412                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1413                    return;
1414                }
1415                ProcessRecord app = (ProcessRecord)msg.obj;
1416                synchronized (ActivityManagerService.this) {
1417                    processStartTimedOutLocked(app);
1418                }
1419            } break;
1420            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1421                synchronized (ActivityManagerService.this) {
1422                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1423                }
1424            } break;
1425            case KILL_APPLICATION_MSG: {
1426                synchronized (ActivityManagerService.this) {
1427                    int appid = msg.arg1;
1428                    boolean restart = (msg.arg2 == 1);
1429                    Bundle bundle = (Bundle)msg.obj;
1430                    String pkg = bundle.getString("pkg");
1431                    String reason = bundle.getString("reason");
1432                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1433                            false, UserHandle.USER_ALL, reason);
1434                }
1435            } break;
1436            case FINALIZE_PENDING_INTENT_MSG: {
1437                ((PendingIntentRecord)msg.obj).completeFinalize();
1438            } break;
1439            case POST_HEAVY_NOTIFICATION_MSG: {
1440                INotificationManager inm = NotificationManager.getService();
1441                if (inm == null) {
1442                    return;
1443                }
1444
1445                ActivityRecord root = (ActivityRecord)msg.obj;
1446                ProcessRecord process = root.app;
1447                if (process == null) {
1448                    return;
1449                }
1450
1451                try {
1452                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1453                    String text = mContext.getString(R.string.heavy_weight_notification,
1454                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1455                    Notification notification = new Notification();
1456                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1457                    notification.when = 0;
1458                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1459                    notification.tickerText = text;
1460                    notification.defaults = 0; // please be quiet
1461                    notification.sound = null;
1462                    notification.vibrate = null;
1463                    notification.setLatestEventInfo(context, text,
1464                            mContext.getText(R.string.heavy_weight_notification_detail),
1465                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1466                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1467                                    new UserHandle(root.userId)));
1468
1469                    try {
1470                        int[] outId = new int[1];
1471                        inm.enqueueNotificationWithTag("android", "android", null,
1472                                R.string.heavy_weight_notification,
1473                                notification, outId, root.userId);
1474                    } catch (RuntimeException e) {
1475                        Slog.w(ActivityManagerService.TAG,
1476                                "Error showing notification for heavy-weight app", e);
1477                    } catch (RemoteException e) {
1478                    }
1479                } catch (NameNotFoundException e) {
1480                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1481                }
1482            } break;
1483            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1484                INotificationManager inm = NotificationManager.getService();
1485                if (inm == null) {
1486                    return;
1487                }
1488                try {
1489                    inm.cancelNotificationWithTag("android", null,
1490                            R.string.heavy_weight_notification,  msg.arg1);
1491                } catch (RuntimeException e) {
1492                    Slog.w(ActivityManagerService.TAG,
1493                            "Error canceling notification for service", e);
1494                } catch (RemoteException e) {
1495                }
1496            } break;
1497            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1498                synchronized (ActivityManagerService.this) {
1499                    checkExcessivePowerUsageLocked(true);
1500                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1501                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1502                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1503                }
1504            } break;
1505            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1506                synchronized (ActivityManagerService.this) {
1507                    ActivityRecord ar = (ActivityRecord)msg.obj;
1508                    if (mCompatModeDialog != null) {
1509                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1510                                ar.info.applicationInfo.packageName)) {
1511                            return;
1512                        }
1513                        mCompatModeDialog.dismiss();
1514                        mCompatModeDialog = null;
1515                    }
1516                    if (ar != null && false) {
1517                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1518                                ar.packageName)) {
1519                            int mode = mCompatModePackages.computeCompatModeLocked(
1520                                    ar.info.applicationInfo);
1521                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1522                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1523                                mCompatModeDialog = new CompatModeDialog(
1524                                        ActivityManagerService.this, mContext,
1525                                        ar.info.applicationInfo);
1526                                mCompatModeDialog.show();
1527                            }
1528                        }
1529                    }
1530                }
1531                break;
1532            }
1533            case DISPATCH_PROCESSES_CHANGED: {
1534                dispatchProcessesChanged();
1535                break;
1536            }
1537            case DISPATCH_PROCESS_DIED: {
1538                final int pid = msg.arg1;
1539                final int uid = msg.arg2;
1540                dispatchProcessDied(pid, uid);
1541                break;
1542            }
1543            case REPORT_MEM_USAGE_MSG: {
1544                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1545                Thread thread = new Thread() {
1546                    @Override public void run() {
1547                        final SparseArray<ProcessMemInfo> infoMap
1548                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1549                        for (int i=0, N=memInfos.size(); i<N; i++) {
1550                            ProcessMemInfo mi = memInfos.get(i);
1551                            infoMap.put(mi.pid, mi);
1552                        }
1553                        updateCpuStatsNow();
1554                        synchronized (mProcessCpuThread) {
1555                            final int N = mProcessCpuTracker.countStats();
1556                            for (int i=0; i<N; i++) {
1557                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1558                                if (st.vsize > 0) {
1559                                    long pss = Debug.getPss(st.pid, null);
1560                                    if (pss > 0) {
1561                                        if (infoMap.indexOfKey(st.pid) < 0) {
1562                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1563                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1564                                            mi.pss = pss;
1565                                            memInfos.add(mi);
1566                                        }
1567                                    }
1568                                }
1569                            }
1570                        }
1571
1572                        long totalPss = 0;
1573                        for (int i=0, N=memInfos.size(); i<N; i++) {
1574                            ProcessMemInfo mi = memInfos.get(i);
1575                            if (mi.pss == 0) {
1576                                mi.pss = Debug.getPss(mi.pid, null);
1577                            }
1578                            totalPss += mi.pss;
1579                        }
1580                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1581                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1582                                if (lhs.oomAdj != rhs.oomAdj) {
1583                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1584                                }
1585                                if (lhs.pss != rhs.pss) {
1586                                    return lhs.pss < rhs.pss ? 1 : -1;
1587                                }
1588                                return 0;
1589                            }
1590                        });
1591
1592                        StringBuilder tag = new StringBuilder(128);
1593                        StringBuilder stack = new StringBuilder(128);
1594                        tag.append("Low on memory -- ");
1595                        appendMemBucket(tag, totalPss, "total", false);
1596                        appendMemBucket(stack, totalPss, "total", true);
1597
1598                        StringBuilder logBuilder = new StringBuilder(1024);
1599                        logBuilder.append("Low on memory:\n");
1600
1601                        boolean firstLine = true;
1602                        int lastOomAdj = Integer.MIN_VALUE;
1603                        for (int i=0, N=memInfos.size(); i<N; i++) {
1604                            ProcessMemInfo mi = memInfos.get(i);
1605
1606                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1607                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1608                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1609                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1610                                if (lastOomAdj != mi.oomAdj) {
1611                                    lastOomAdj = mi.oomAdj;
1612                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1613                                        tag.append(" / ");
1614                                    }
1615                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1616                                        if (firstLine) {
1617                                            stack.append(":");
1618                                            firstLine = false;
1619                                        }
1620                                        stack.append("\n\t at ");
1621                                    } else {
1622                                        stack.append("$");
1623                                    }
1624                                } else {
1625                                    tag.append(" ");
1626                                    stack.append("$");
1627                                }
1628                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1629                                    appendMemBucket(tag, mi.pss, mi.name, false);
1630                                }
1631                                appendMemBucket(stack, mi.pss, mi.name, true);
1632                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1633                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1634                                    stack.append("(");
1635                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1636                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1637                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1638                                            stack.append(":");
1639                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1640                                        }
1641                                    }
1642                                    stack.append(")");
1643                                }
1644                            }
1645
1646                            logBuilder.append("  ");
1647                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1648                            logBuilder.append(' ');
1649                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1650                            logBuilder.append(' ');
1651                            ProcessList.appendRamKb(logBuilder, mi.pss);
1652                            logBuilder.append(" kB: ");
1653                            logBuilder.append(mi.name);
1654                            logBuilder.append(" (");
1655                            logBuilder.append(mi.pid);
1656                            logBuilder.append(") ");
1657                            logBuilder.append(mi.adjType);
1658                            logBuilder.append('\n');
1659                            if (mi.adjReason != null) {
1660                                logBuilder.append("                      ");
1661                                logBuilder.append(mi.adjReason);
1662                                logBuilder.append('\n');
1663                            }
1664                        }
1665
1666                        logBuilder.append("           ");
1667                        ProcessList.appendRamKb(logBuilder, totalPss);
1668                        logBuilder.append(" kB: TOTAL\n");
1669
1670                        long[] infos = new long[Debug.MEMINFO_COUNT];
1671                        Debug.getMemInfo(infos);
1672                        logBuilder.append("  MemInfo: ");
1673                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1674                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1675                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1676                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1677                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1678                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1679                            logBuilder.append("  ZRAM: ");
1680                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1681                            logBuilder.append(" kB RAM, ");
1682                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1683                            logBuilder.append(" kB swap total, ");
1684                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1685                            logBuilder.append(" kB swap free\n");
1686                        }
1687                        Slog.i(TAG, logBuilder.toString());
1688
1689                        StringBuilder dropBuilder = new StringBuilder(1024);
1690                        /*
1691                        StringWriter oomSw = new StringWriter();
1692                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1693                        StringWriter catSw = new StringWriter();
1694                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1695                        String[] emptyArgs = new String[] { };
1696                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1697                        oomPw.flush();
1698                        String oomString = oomSw.toString();
1699                        */
1700                        dropBuilder.append(stack);
1701                        dropBuilder.append('\n');
1702                        dropBuilder.append('\n');
1703                        dropBuilder.append(logBuilder);
1704                        dropBuilder.append('\n');
1705                        /*
1706                        dropBuilder.append(oomString);
1707                        dropBuilder.append('\n');
1708                        */
1709                        StringWriter catSw = new StringWriter();
1710                        synchronized (ActivityManagerService.this) {
1711                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1712                            String[] emptyArgs = new String[] { };
1713                            catPw.println();
1714                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1715                            catPw.println();
1716                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1717                                    false, false, null);
1718                            catPw.println();
1719                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1720                            catPw.flush();
1721                        }
1722                        dropBuilder.append(catSw.toString());
1723                        addErrorToDropBox("lowmem", null, "system_server", null,
1724                                null, tag.toString(), dropBuilder.toString(), null, null);
1725                        //Slog.i(TAG, "Sent to dropbox:");
1726                        //Slog.i(TAG, dropBuilder.toString());
1727                        synchronized (ActivityManagerService.this) {
1728                            long now = SystemClock.uptimeMillis();
1729                            if (mLastMemUsageReportTime < now) {
1730                                mLastMemUsageReportTime = now;
1731                            }
1732                        }
1733                    }
1734                };
1735                thread.start();
1736                break;
1737            }
1738            case REPORT_USER_SWITCH_MSG: {
1739                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1740                break;
1741            }
1742            case CONTINUE_USER_SWITCH_MSG: {
1743                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1744                break;
1745            }
1746            case USER_SWITCH_TIMEOUT_MSG: {
1747                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1748                break;
1749            }
1750            case IMMERSIVE_MODE_LOCK_MSG: {
1751                final boolean nextState = (msg.arg1 != 0);
1752                if (mUpdateLock.isHeld() != nextState) {
1753                    if (DEBUG_IMMERSIVE) {
1754                        final ActivityRecord r = (ActivityRecord) msg.obj;
1755                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1756                    }
1757                    if (nextState) {
1758                        mUpdateLock.acquire();
1759                    } else {
1760                        mUpdateLock.release();
1761                    }
1762                }
1763                break;
1764            }
1765            case PERSIST_URI_GRANTS_MSG: {
1766                writeGrantedUriPermissions();
1767                break;
1768            }
1769            case REQUEST_ALL_PSS_MSG: {
1770                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1771                break;
1772            }
1773            case START_PROFILES_MSG: {
1774                synchronized (ActivityManagerService.this) {
1775                    startProfilesLocked();
1776                }
1777                break;
1778            }
1779            case UPDATE_TIME: {
1780                synchronized (ActivityManagerService.this) {
1781                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1782                        ProcessRecord r = mLruProcesses.get(i);
1783                        if (r.thread != null) {
1784                            try {
1785                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1786                            } catch (RemoteException ex) {
1787                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1788                            }
1789                        }
1790                    }
1791                }
1792                break;
1793            }
1794            case SYSTEM_USER_START_MSG: {
1795                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1796                        Integer.toString(msg.arg1), msg.arg1);
1797                mSystemServiceManager.startUser(msg.arg1);
1798                break;
1799            }
1800            case SYSTEM_USER_CURRENT_MSG: {
1801                mBatteryStatsService.noteEvent(
1802                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1803                        Integer.toString(msg.arg2), msg.arg2);
1804                mBatteryStatsService.noteEvent(
1805                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1806                        Integer.toString(msg.arg1), msg.arg1);
1807                mSystemServiceManager.switchUser(msg.arg1);
1808                break;
1809            }
1810            }
1811        }
1812    };
1813
1814    static final int COLLECT_PSS_BG_MSG = 1;
1815
1816    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1817        @Override
1818        public void handleMessage(Message msg) {
1819            switch (msg.what) {
1820            case COLLECT_PSS_BG_MSG: {
1821                long start = SystemClock.uptimeMillis();
1822                MemInfoReader memInfo = null;
1823                synchronized (ActivityManagerService.this) {
1824                    if (mFullPssPending) {
1825                        mFullPssPending = false;
1826                        memInfo = new MemInfoReader();
1827                    }
1828                }
1829                if (memInfo != null) {
1830                    updateCpuStatsNow();
1831                    long nativeTotalPss = 0;
1832                    synchronized (mProcessCpuThread) {
1833                        final int N = mProcessCpuTracker.countStats();
1834                        for (int j=0; j<N; j++) {
1835                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1836                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1837                                // This is definitely an application process; skip it.
1838                                continue;
1839                            }
1840                            synchronized (mPidsSelfLocked) {
1841                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1842                                    // This is one of our own processes; skip it.
1843                                    continue;
1844                                }
1845                            }
1846                            nativeTotalPss += Debug.getPss(st.pid, null);
1847                        }
1848                    }
1849                    memInfo.readMemInfo();
1850                    synchronized (this) {
1851                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1852                                + (SystemClock.uptimeMillis()-start) + "ms");
1853                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1854                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1855                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1856                                        +memInfo.getSlabSizeKb(),
1857                                nativeTotalPss);
1858                    }
1859                }
1860
1861                int i=0, num=0;
1862                long[] tmp = new long[1];
1863                do {
1864                    ProcessRecord proc;
1865                    int procState;
1866                    int pid;
1867                    synchronized (ActivityManagerService.this) {
1868                        if (i >= mPendingPssProcesses.size()) {
1869                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1870                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1871                            mPendingPssProcesses.clear();
1872                            return;
1873                        }
1874                        proc = mPendingPssProcesses.get(i);
1875                        procState = proc.pssProcState;
1876                        if (proc.thread != null && procState == proc.setProcState) {
1877                            pid = proc.pid;
1878                        } else {
1879                            proc = null;
1880                            pid = 0;
1881                        }
1882                        i++;
1883                    }
1884                    if (proc != null) {
1885                        long pss = Debug.getPss(pid, tmp);
1886                        synchronized (ActivityManagerService.this) {
1887                            if (proc.thread != null && proc.setProcState == procState
1888                                    && proc.pid == pid) {
1889                                num++;
1890                                proc.lastPssTime = SystemClock.uptimeMillis();
1891                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1892                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1893                                        + ": " + pss + " lastPss=" + proc.lastPss
1894                                        + " state=" + ProcessList.makeProcStateString(procState));
1895                                if (proc.initialIdlePss == 0) {
1896                                    proc.initialIdlePss = pss;
1897                                }
1898                                proc.lastPss = pss;
1899                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1900                                    proc.lastCachedPss = pss;
1901                                }
1902                            }
1903                        }
1904                    }
1905                } while (true);
1906            }
1907            }
1908        }
1909    };
1910
1911    /**
1912     * Monitor for package changes and update our internal state.
1913     */
1914    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1915        @Override
1916        public void onPackageRemoved(String packageName, int uid) {
1917            // Remove all tasks with activities in the specified package from the list of recent tasks
1918            synchronized (ActivityManagerService.this) {
1919                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1920                    TaskRecord tr = mRecentTasks.get(i);
1921                    ComponentName cn = tr.intent.getComponent();
1922                    if (cn != null && cn.getPackageName().equals(packageName)) {
1923                        // If the package name matches, remove the task and kill the process
1924                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1925                    }
1926                }
1927            }
1928        }
1929
1930        @Override
1931        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1932            onPackageModified(packageName);
1933            return true;
1934        }
1935
1936        @Override
1937        public void onPackageModified(String packageName) {
1938            final PackageManager pm = mContext.getPackageManager();
1939            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1940                    new ArrayList<Pair<Intent, Integer>>();
1941            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1942            // Copy the list of recent tasks so that we don't hold onto the lock on
1943            // ActivityManagerService for long periods while checking if components exist.
1944            synchronized (ActivityManagerService.this) {
1945                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1946                    TaskRecord tr = mRecentTasks.get(i);
1947                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1948                }
1949            }
1950            // Check the recent tasks and filter out all tasks with components that no longer exist.
1951            Intent tmpI = new Intent();
1952            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1953                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1954                ComponentName cn = p.first.getComponent();
1955                if (cn != null && cn.getPackageName().equals(packageName)) {
1956                    try {
1957                        // Add the task to the list to remove if the component no longer exists
1958                        tmpI.setComponent(cn);
1959                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1960                            tasksToRemove.add(p.second);
1961                        }
1962                    } catch (Exception e) {}
1963                }
1964            }
1965            // Prune all the tasks with removed components from the list of recent tasks
1966            synchronized (ActivityManagerService.this) {
1967                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1968                    // Remove the task but don't kill the process (since other components in that
1969                    // package may still be running and in the background)
1970                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1971                }
1972            }
1973        }
1974
1975        @Override
1976        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1977            // Force stop the specified packages
1978            if (packages != null) {
1979                for (String pkg : packages) {
1980                    synchronized (ActivityManagerService.this) {
1981                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1982                                "finished booting")) {
1983                            return true;
1984                        }
1985                    }
1986                }
1987            }
1988            return false;
1989        }
1990    };
1991
1992    public void setSystemProcess() {
1993        try {
1994            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1995            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1996            ServiceManager.addService("meminfo", new MemBinder(this));
1997            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1998            ServiceManager.addService("dbinfo", new DbBinder(this));
1999            if (MONITOR_CPU_USAGE) {
2000                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2001            }
2002            ServiceManager.addService("permission", new PermissionController(this));
2003
2004            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2005                    "android", STOCK_PM_FLAGS);
2006            mSystemThread.installSystemApplicationInfo(info);
2007
2008            synchronized (this) {
2009                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2010                app.persistent = true;
2011                app.pid = MY_PID;
2012                app.maxAdj = ProcessList.SYSTEM_ADJ;
2013                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2014                mProcessNames.put(app.processName, app.uid, app);
2015                synchronized (mPidsSelfLocked) {
2016                    mPidsSelfLocked.put(app.pid, app);
2017                }
2018                updateLruProcessLocked(app, false, null);
2019                updateOomAdjLocked();
2020            }
2021        } catch (PackageManager.NameNotFoundException e) {
2022            throw new RuntimeException(
2023                    "Unable to find android system package", e);
2024        }
2025    }
2026
2027    public void setWindowManager(WindowManagerService wm) {
2028        mWindowManager = wm;
2029        mStackSupervisor.setWindowManager(wm);
2030    }
2031
2032    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2033        mUsageStatsService = usageStatsManager;
2034    }
2035
2036    public void startObservingNativeCrashes() {
2037        final NativeCrashListener ncl = new NativeCrashListener(this);
2038        ncl.start();
2039    }
2040
2041    public IAppOpsService getAppOpsService() {
2042        return mAppOpsService;
2043    }
2044
2045    static class MemBinder extends Binder {
2046        ActivityManagerService mActivityManagerService;
2047        MemBinder(ActivityManagerService activityManagerService) {
2048            mActivityManagerService = activityManagerService;
2049        }
2050
2051        @Override
2052        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2053            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2054                    != PackageManager.PERMISSION_GRANTED) {
2055                pw.println("Permission Denial: can't dump meminfo from from pid="
2056                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2057                        + " without permission " + android.Manifest.permission.DUMP);
2058                return;
2059            }
2060
2061            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2062        }
2063    }
2064
2065    static class GraphicsBinder extends Binder {
2066        ActivityManagerService mActivityManagerService;
2067        GraphicsBinder(ActivityManagerService activityManagerService) {
2068            mActivityManagerService = activityManagerService;
2069        }
2070
2071        @Override
2072        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2073            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2074                    != PackageManager.PERMISSION_GRANTED) {
2075                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2076                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2077                        + " without permission " + android.Manifest.permission.DUMP);
2078                return;
2079            }
2080
2081            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2082        }
2083    }
2084
2085    static class DbBinder extends Binder {
2086        ActivityManagerService mActivityManagerService;
2087        DbBinder(ActivityManagerService activityManagerService) {
2088            mActivityManagerService = activityManagerService;
2089        }
2090
2091        @Override
2092        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2093            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2094                    != PackageManager.PERMISSION_GRANTED) {
2095                pw.println("Permission Denial: can't dump dbinfo from from pid="
2096                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2097                        + " without permission " + android.Manifest.permission.DUMP);
2098                return;
2099            }
2100
2101            mActivityManagerService.dumpDbInfo(fd, pw, args);
2102        }
2103    }
2104
2105    static class CpuBinder extends Binder {
2106        ActivityManagerService mActivityManagerService;
2107        CpuBinder(ActivityManagerService activityManagerService) {
2108            mActivityManagerService = activityManagerService;
2109        }
2110
2111        @Override
2112        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2113            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2114                    != PackageManager.PERMISSION_GRANTED) {
2115                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2116                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2117                        + " without permission " + android.Manifest.permission.DUMP);
2118                return;
2119            }
2120
2121            synchronized (mActivityManagerService.mProcessCpuThread) {
2122                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2123                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2124                        SystemClock.uptimeMillis()));
2125            }
2126        }
2127    }
2128
2129    public static final class Lifecycle extends SystemService {
2130        private final ActivityManagerService mService;
2131
2132        public Lifecycle(Context context) {
2133            super(context);
2134            mService = new ActivityManagerService(context);
2135        }
2136
2137        @Override
2138        public void onStart() {
2139            mService.start();
2140        }
2141
2142        public ActivityManagerService getService() {
2143            return mService;
2144        }
2145    }
2146
2147    // Note: This method is invoked on the main thread but may need to attach various
2148    // handlers to other threads.  So take care to be explicit about the looper.
2149    public ActivityManagerService(Context systemContext) {
2150        mContext = systemContext;
2151        mFactoryTest = FactoryTest.getMode();
2152        mSystemThread = ActivityThread.currentActivityThread();
2153
2154        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2155
2156        mHandlerThread = new ServiceThread(TAG,
2157                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2158        mHandlerThread.start();
2159        mHandler = new MainHandler(mHandlerThread.getLooper());
2160
2161        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2162                "foreground", BROADCAST_FG_TIMEOUT, false);
2163        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2164                "background", BROADCAST_BG_TIMEOUT, true);
2165        mBroadcastQueues[0] = mFgBroadcastQueue;
2166        mBroadcastQueues[1] = mBgBroadcastQueue;
2167
2168        mServices = new ActiveServices(this);
2169        mProviderMap = new ProviderMap(this);
2170
2171        // TODO: Move creation of battery stats service outside of activity manager service.
2172        File dataDir = Environment.getDataDirectory();
2173        File systemDir = new File(dataDir, "system");
2174        systemDir.mkdirs();
2175        mBatteryStatsService = new BatteryStatsService(new File(
2176                systemDir, "batterystats.bin").toString(), mHandler);
2177        mBatteryStatsService.getActiveStatistics().readLocked();
2178        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2179        mOnBattery = DEBUG_POWER ? true
2180                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2181        mBatteryStatsService.getActiveStatistics().setCallback(this);
2182
2183        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2184
2185        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2186
2187        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2188
2189        // User 0 is the first and only user that runs at boot.
2190        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2191        mUserLru.add(Integer.valueOf(0));
2192        updateStartedUserArrayLocked();
2193
2194        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2195            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2196
2197        mConfiguration.setToDefaults();
2198        mConfiguration.setLocale(Locale.getDefault());
2199
2200        mConfigurationSeq = mConfiguration.seq = 1;
2201        mProcessCpuTracker.init();
2202
2203        mHasRecents = mContext.getResources().getBoolean(
2204                com.android.internal.R.bool.config_hasRecents);
2205
2206        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2207        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2208        mStackSupervisor = new ActivityStackSupervisor(this);
2209        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2210
2211        mProcessCpuThread = new Thread("CpuTracker") {
2212            @Override
2213            public void run() {
2214                while (true) {
2215                    try {
2216                        try {
2217                            synchronized(this) {
2218                                final long now = SystemClock.uptimeMillis();
2219                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2220                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2221                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2222                                //        + ", write delay=" + nextWriteDelay);
2223                                if (nextWriteDelay < nextCpuDelay) {
2224                                    nextCpuDelay = nextWriteDelay;
2225                                }
2226                                if (nextCpuDelay > 0) {
2227                                    mProcessCpuMutexFree.set(true);
2228                                    this.wait(nextCpuDelay);
2229                                }
2230                            }
2231                        } catch (InterruptedException e) {
2232                        }
2233                        updateCpuStatsNow();
2234                    } catch (Exception e) {
2235                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2236                    }
2237                }
2238            }
2239        };
2240
2241        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2242
2243        Watchdog.getInstance().addMonitor(this);
2244        Watchdog.getInstance().addThread(mHandler);
2245    }
2246
2247    public void setSystemServiceManager(SystemServiceManager mgr) {
2248        mSystemServiceManager = mgr;
2249    }
2250
2251    private void start() {
2252        Process.removeAllProcessGroups();
2253        mProcessCpuThread.start();
2254
2255        mBatteryStatsService.publish(mContext);
2256        mAppOpsService.publish(mContext);
2257        Slog.d("AppOps", "AppOpsService published");
2258        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2259    }
2260
2261    public void initPowerManagement() {
2262        mStackSupervisor.initPowerManagement();
2263        mBatteryStatsService.initPowerManagement();
2264    }
2265
2266    @Override
2267    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2268            throws RemoteException {
2269        if (code == SYSPROPS_TRANSACTION) {
2270            // We need to tell all apps about the system property change.
2271            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2272            synchronized(this) {
2273                final int NP = mProcessNames.getMap().size();
2274                for (int ip=0; ip<NP; ip++) {
2275                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2276                    final int NA = apps.size();
2277                    for (int ia=0; ia<NA; ia++) {
2278                        ProcessRecord app = apps.valueAt(ia);
2279                        if (app.thread != null) {
2280                            procs.add(app.thread.asBinder());
2281                        }
2282                    }
2283                }
2284            }
2285
2286            int N = procs.size();
2287            for (int i=0; i<N; i++) {
2288                Parcel data2 = Parcel.obtain();
2289                try {
2290                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2291                } catch (RemoteException e) {
2292                }
2293                data2.recycle();
2294            }
2295        }
2296        try {
2297            return super.onTransact(code, data, reply, flags);
2298        } catch (RuntimeException e) {
2299            // The activity manager only throws security exceptions, so let's
2300            // log all others.
2301            if (!(e instanceof SecurityException)) {
2302                Slog.wtf(TAG, "Activity Manager Crash", e);
2303            }
2304            throw e;
2305        }
2306    }
2307
2308    void updateCpuStats() {
2309        final long now = SystemClock.uptimeMillis();
2310        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2311            return;
2312        }
2313        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2314            synchronized (mProcessCpuThread) {
2315                mProcessCpuThread.notify();
2316            }
2317        }
2318    }
2319
2320    void updateCpuStatsNow() {
2321        synchronized (mProcessCpuThread) {
2322            mProcessCpuMutexFree.set(false);
2323            final long now = SystemClock.uptimeMillis();
2324            boolean haveNewCpuStats = false;
2325
2326            if (MONITOR_CPU_USAGE &&
2327                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2328                mLastCpuTime.set(now);
2329                haveNewCpuStats = true;
2330                mProcessCpuTracker.update();
2331                //Slog.i(TAG, mProcessCpu.printCurrentState());
2332                //Slog.i(TAG, "Total CPU usage: "
2333                //        + mProcessCpu.getTotalCpuPercent() + "%");
2334
2335                // Slog the cpu usage if the property is set.
2336                if ("true".equals(SystemProperties.get("events.cpu"))) {
2337                    int user = mProcessCpuTracker.getLastUserTime();
2338                    int system = mProcessCpuTracker.getLastSystemTime();
2339                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2340                    int irq = mProcessCpuTracker.getLastIrqTime();
2341                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2342                    int idle = mProcessCpuTracker.getLastIdleTime();
2343
2344                    int total = user + system + iowait + irq + softIrq + idle;
2345                    if (total == 0) total = 1;
2346
2347                    EventLog.writeEvent(EventLogTags.CPU,
2348                            ((user+system+iowait+irq+softIrq) * 100) / total,
2349                            (user * 100) / total,
2350                            (system * 100) / total,
2351                            (iowait * 100) / total,
2352                            (irq * 100) / total,
2353                            (softIrq * 100) / total);
2354                }
2355            }
2356
2357            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2358            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2359            synchronized(bstats) {
2360                synchronized(mPidsSelfLocked) {
2361                    if (haveNewCpuStats) {
2362                        if (mOnBattery) {
2363                            int perc = bstats.startAddingCpuLocked();
2364                            int totalUTime = 0;
2365                            int totalSTime = 0;
2366                            final int N = mProcessCpuTracker.countStats();
2367                            for (int i=0; i<N; i++) {
2368                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2369                                if (!st.working) {
2370                                    continue;
2371                                }
2372                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2373                                int otherUTime = (st.rel_utime*perc)/100;
2374                                int otherSTime = (st.rel_stime*perc)/100;
2375                                totalUTime += otherUTime;
2376                                totalSTime += otherSTime;
2377                                if (pr != null) {
2378                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2379                                    if (ps == null || !ps.isActive()) {
2380                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2381                                                pr.info.uid, pr.processName);
2382                                    }
2383                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2384                                            st.rel_stime-otherSTime);
2385                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2386                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2387                                } else {
2388                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2389                                    if (ps == null || !ps.isActive()) {
2390                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2391                                                bstats.mapUid(st.uid), st.name);
2392                                    }
2393                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2394                                            st.rel_stime-otherSTime);
2395                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2396                                }
2397                            }
2398                            bstats.finishAddingCpuLocked(perc, totalUTime,
2399                                    totalSTime, cpuSpeedTimes);
2400                        }
2401                    }
2402                }
2403
2404                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2405                    mLastWriteTime = now;
2406                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2407                }
2408            }
2409        }
2410    }
2411
2412    @Override
2413    public void batteryNeedsCpuUpdate() {
2414        updateCpuStatsNow();
2415    }
2416
2417    @Override
2418    public void batteryPowerChanged(boolean onBattery) {
2419        // When plugging in, update the CPU stats first before changing
2420        // the plug state.
2421        updateCpuStatsNow();
2422        synchronized (this) {
2423            synchronized(mPidsSelfLocked) {
2424                mOnBattery = DEBUG_POWER ? true : onBattery;
2425            }
2426        }
2427    }
2428
2429    /**
2430     * Initialize the application bind args. These are passed to each
2431     * process when the bindApplication() IPC is sent to the process. They're
2432     * lazily setup to make sure the services are running when they're asked for.
2433     */
2434    private HashMap<String, IBinder> getCommonServicesLocked() {
2435        if (mAppBindArgs == null) {
2436            mAppBindArgs = new HashMap<String, IBinder>();
2437
2438            // Setup the application init args
2439            mAppBindArgs.put("package", ServiceManager.getService("package"));
2440            mAppBindArgs.put("window", ServiceManager.getService("window"));
2441            mAppBindArgs.put(Context.ALARM_SERVICE,
2442                    ServiceManager.getService(Context.ALARM_SERVICE));
2443        }
2444        return mAppBindArgs;
2445    }
2446
2447    final void setFocusedActivityLocked(ActivityRecord r) {
2448        if (mFocusedActivity != r) {
2449            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2450            mFocusedActivity = r;
2451            if (r.task != null && r.task.voiceInteractor != null) {
2452                startRunningVoiceLocked();
2453            } else {
2454                finishRunningVoiceLocked();
2455            }
2456            mStackSupervisor.setFocusedStack(r);
2457            if (r != null) {
2458                mWindowManager.setFocusedApp(r.appToken, true);
2459            }
2460            applyUpdateLockStateLocked(r);
2461        }
2462    }
2463
2464    final void clearFocusedActivity(ActivityRecord r) {
2465        if (mFocusedActivity == r) {
2466            mFocusedActivity = null;
2467        }
2468    }
2469
2470    @Override
2471    public void setFocusedStack(int stackId) {
2472        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2473        synchronized (ActivityManagerService.this) {
2474            ActivityStack stack = mStackSupervisor.getStack(stackId);
2475            if (stack != null) {
2476                ActivityRecord r = stack.topRunningActivityLocked(null);
2477                if (r != null) {
2478                    setFocusedActivityLocked(r);
2479                }
2480            }
2481        }
2482    }
2483
2484    @Override
2485    public void notifyActivityDrawn(IBinder token) {
2486        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2487        synchronized (this) {
2488            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2489            if (r != null) {
2490                r.task.stack.notifyActivityDrawnLocked(r);
2491            }
2492        }
2493    }
2494
2495    final void applyUpdateLockStateLocked(ActivityRecord r) {
2496        // Modifications to the UpdateLock state are done on our handler, outside
2497        // the activity manager's locks.  The new state is determined based on the
2498        // state *now* of the relevant activity record.  The object is passed to
2499        // the handler solely for logging detail, not to be consulted/modified.
2500        final boolean nextState = r != null && r.immersive;
2501        mHandler.sendMessage(
2502                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2503    }
2504
2505    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2506        Message msg = Message.obtain();
2507        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2508        msg.obj = r.task.askedCompatMode ? null : r;
2509        mHandler.sendMessage(msg);
2510    }
2511
2512    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2513            String what, Object obj, ProcessRecord srcApp) {
2514        app.lastActivityTime = now;
2515
2516        if (app.activities.size() > 0) {
2517            // Don't want to touch dependent processes that are hosting activities.
2518            return index;
2519        }
2520
2521        int lrui = mLruProcesses.lastIndexOf(app);
2522        if (lrui < 0) {
2523            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2524                    + what + " " + obj + " from " + srcApp);
2525            return index;
2526        }
2527
2528        if (lrui >= index) {
2529            // Don't want to cause this to move dependent processes *back* in the
2530            // list as if they were less frequently used.
2531            return index;
2532        }
2533
2534        if (lrui >= mLruProcessActivityStart) {
2535            // Don't want to touch dependent processes that are hosting activities.
2536            return index;
2537        }
2538
2539        mLruProcesses.remove(lrui);
2540        if (index > 0) {
2541            index--;
2542        }
2543        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2544                + " in LRU list: " + app);
2545        mLruProcesses.add(index, app);
2546        return index;
2547    }
2548
2549    final void removeLruProcessLocked(ProcessRecord app) {
2550        int lrui = mLruProcesses.lastIndexOf(app);
2551        if (lrui >= 0) {
2552            if (lrui <= mLruProcessActivityStart) {
2553                mLruProcessActivityStart--;
2554            }
2555            if (lrui <= mLruProcessServiceStart) {
2556                mLruProcessServiceStart--;
2557            }
2558            mLruProcesses.remove(lrui);
2559        }
2560    }
2561
2562    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2563            ProcessRecord client) {
2564        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2565                || app.treatLikeActivity;
2566        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2567        if (!activityChange && hasActivity) {
2568            // The process has activities, so we are only allowing activity-based adjustments
2569            // to move it.  It should be kept in the front of the list with other
2570            // processes that have activities, and we don't want those to change their
2571            // order except due to activity operations.
2572            return;
2573        }
2574
2575        mLruSeq++;
2576        final long now = SystemClock.uptimeMillis();
2577        app.lastActivityTime = now;
2578
2579        // First a quick reject: if the app is already at the position we will
2580        // put it, then there is nothing to do.
2581        if (hasActivity) {
2582            final int N = mLruProcesses.size();
2583            if (N > 0 && mLruProcesses.get(N-1) == app) {
2584                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2585                return;
2586            }
2587        } else {
2588            if (mLruProcessServiceStart > 0
2589                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2590                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2591                return;
2592            }
2593        }
2594
2595        int lrui = mLruProcesses.lastIndexOf(app);
2596
2597        if (app.persistent && lrui >= 0) {
2598            // We don't care about the position of persistent processes, as long as
2599            // they are in the list.
2600            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2601            return;
2602        }
2603
2604        /* In progress: compute new position first, so we can avoid doing work
2605           if the process is not actually going to move.  Not yet working.
2606        int addIndex;
2607        int nextIndex;
2608        boolean inActivity = false, inService = false;
2609        if (hasActivity) {
2610            // Process has activities, put it at the very tipsy-top.
2611            addIndex = mLruProcesses.size();
2612            nextIndex = mLruProcessServiceStart;
2613            inActivity = true;
2614        } else if (hasService) {
2615            // Process has services, put it at the top of the service list.
2616            addIndex = mLruProcessActivityStart;
2617            nextIndex = mLruProcessServiceStart;
2618            inActivity = true;
2619            inService = true;
2620        } else  {
2621            // Process not otherwise of interest, it goes to the top of the non-service area.
2622            addIndex = mLruProcessServiceStart;
2623            if (client != null) {
2624                int clientIndex = mLruProcesses.lastIndexOf(client);
2625                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2626                        + app);
2627                if (clientIndex >= 0 && addIndex > clientIndex) {
2628                    addIndex = clientIndex;
2629                }
2630            }
2631            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2632        }
2633
2634        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2635                + mLruProcessActivityStart + "): " + app);
2636        */
2637
2638        if (lrui >= 0) {
2639            if (lrui < mLruProcessActivityStart) {
2640                mLruProcessActivityStart--;
2641            }
2642            if (lrui < mLruProcessServiceStart) {
2643                mLruProcessServiceStart--;
2644            }
2645            /*
2646            if (addIndex > lrui) {
2647                addIndex--;
2648            }
2649            if (nextIndex > lrui) {
2650                nextIndex--;
2651            }
2652            */
2653            mLruProcesses.remove(lrui);
2654        }
2655
2656        /*
2657        mLruProcesses.add(addIndex, app);
2658        if (inActivity) {
2659            mLruProcessActivityStart++;
2660        }
2661        if (inService) {
2662            mLruProcessActivityStart++;
2663        }
2664        */
2665
2666        int nextIndex;
2667        if (hasActivity) {
2668            final int N = mLruProcesses.size();
2669            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2670                // Process doesn't have activities, but has clients with
2671                // activities...  move it up, but one below the top (the top
2672                // should always have a real activity).
2673                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2674                mLruProcesses.add(N-1, app);
2675                // To keep it from spamming the LRU list (by making a bunch of clients),
2676                // we will push down any other entries owned by the app.
2677                final int uid = app.info.uid;
2678                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2679                    ProcessRecord subProc = mLruProcesses.get(i);
2680                    if (subProc.info.uid == uid) {
2681                        // We want to push this one down the list.  If the process after
2682                        // it is for the same uid, however, don't do so, because we don't
2683                        // want them internally to be re-ordered.
2684                        if (mLruProcesses.get(i-1).info.uid != uid) {
2685                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2686                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2687                            ProcessRecord tmp = mLruProcesses.get(i);
2688                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2689                            mLruProcesses.set(i-1, tmp);
2690                            i--;
2691                        }
2692                    } else {
2693                        // A gap, we can stop here.
2694                        break;
2695                    }
2696                }
2697            } else {
2698                // Process has activities, put it at the very tipsy-top.
2699                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2700                mLruProcesses.add(app);
2701            }
2702            nextIndex = mLruProcessServiceStart;
2703        } else if (hasService) {
2704            // Process has services, put it at the top of the service list.
2705            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2706            mLruProcesses.add(mLruProcessActivityStart, app);
2707            nextIndex = mLruProcessServiceStart;
2708            mLruProcessActivityStart++;
2709        } else  {
2710            // Process not otherwise of interest, it goes to the top of the non-service area.
2711            int index = mLruProcessServiceStart;
2712            if (client != null) {
2713                // If there is a client, don't allow the process to be moved up higher
2714                // in the list than that client.
2715                int clientIndex = mLruProcesses.lastIndexOf(client);
2716                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2717                        + " when updating " + app);
2718                if (clientIndex <= lrui) {
2719                    // Don't allow the client index restriction to push it down farther in the
2720                    // list than it already is.
2721                    clientIndex = lrui;
2722                }
2723                if (clientIndex >= 0 && index > clientIndex) {
2724                    index = clientIndex;
2725                }
2726            }
2727            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2728            mLruProcesses.add(index, app);
2729            nextIndex = index-1;
2730            mLruProcessActivityStart++;
2731            mLruProcessServiceStart++;
2732        }
2733
2734        // If the app is currently using a content provider or service,
2735        // bump those processes as well.
2736        for (int j=app.connections.size()-1; j>=0; j--) {
2737            ConnectionRecord cr = app.connections.valueAt(j);
2738            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2739                    && cr.binding.service.app != null
2740                    && cr.binding.service.app.lruSeq != mLruSeq
2741                    && !cr.binding.service.app.persistent) {
2742                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2743                        "service connection", cr, app);
2744            }
2745        }
2746        for (int j=app.conProviders.size()-1; j>=0; j--) {
2747            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2748            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2749                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2750                        "provider reference", cpr, app);
2751            }
2752        }
2753    }
2754
2755    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2756        if (uid == Process.SYSTEM_UID) {
2757            // The system gets to run in any process.  If there are multiple
2758            // processes with the same uid, just pick the first (this
2759            // should never happen).
2760            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2761            if (procs == null) return null;
2762            final int N = procs.size();
2763            for (int i = 0; i < N; i++) {
2764                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2765            }
2766        }
2767        ProcessRecord proc = mProcessNames.get(processName, uid);
2768        if (false && proc != null && !keepIfLarge
2769                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2770                && proc.lastCachedPss >= 4000) {
2771            // Turn this condition on to cause killing to happen regularly, for testing.
2772            if (proc.baseProcessTracker != null) {
2773                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2774            }
2775            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2776                    + "k from cached");
2777        } else if (proc != null && !keepIfLarge
2778                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2779                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2780            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2781            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2782                if (proc.baseProcessTracker != null) {
2783                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2784                }
2785                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2786                        + "k from cached");
2787            }
2788        }
2789        return proc;
2790    }
2791
2792    void ensurePackageDexOpt(String packageName) {
2793        IPackageManager pm = AppGlobals.getPackageManager();
2794        try {
2795            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2796                mDidDexOpt = true;
2797            }
2798        } catch (RemoteException e) {
2799        }
2800    }
2801
2802    boolean isNextTransitionForward() {
2803        int transit = mWindowManager.getPendingAppTransition();
2804        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2805                || transit == AppTransition.TRANSIT_TASK_OPEN
2806                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2807    }
2808
2809    final ProcessRecord startProcessLocked(String processName,
2810            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2811            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2812            boolean isolated, boolean keepIfLarge) {
2813        ProcessRecord app;
2814        if (!isolated) {
2815            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2816        } else {
2817            // If this is an isolated process, it can't re-use an existing process.
2818            app = null;
2819        }
2820        // We don't have to do anything more if:
2821        // (1) There is an existing application record; and
2822        // (2) The caller doesn't think it is dead, OR there is no thread
2823        //     object attached to it so we know it couldn't have crashed; and
2824        // (3) There is a pid assigned to it, so it is either starting or
2825        //     already running.
2826        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2827                + " app=" + app + " knownToBeDead=" + knownToBeDead
2828                + " thread=" + (app != null ? app.thread : null)
2829                + " pid=" + (app != null ? app.pid : -1));
2830        if (app != null && app.pid > 0) {
2831            if (!knownToBeDead || app.thread == null) {
2832                // We already have the app running, or are waiting for it to
2833                // come up (we have a pid but not yet its thread), so keep it.
2834                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2835                // If this is a new package in the process, add the package to the list
2836                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2837                return app;
2838            }
2839
2840            // An application record is attached to a previous process,
2841            // clean it up now.
2842            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2843            Process.killProcessGroup(app.info.uid, app.pid);
2844            handleAppDiedLocked(app, true, true);
2845        }
2846
2847        String hostingNameStr = hostingName != null
2848                ? hostingName.flattenToShortString() : null;
2849
2850        if (!isolated) {
2851            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2852                // If we are in the background, then check to see if this process
2853                // is bad.  If so, we will just silently fail.
2854                if (mBadProcesses.get(info.processName, info.uid) != null) {
2855                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2856                            + "/" + info.processName);
2857                    return null;
2858                }
2859            } else {
2860                // When the user is explicitly starting a process, then clear its
2861                // crash count so that we won't make it bad until they see at
2862                // least one crash dialog again, and make the process good again
2863                // if it had been bad.
2864                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2865                        + "/" + info.processName);
2866                mProcessCrashTimes.remove(info.processName, info.uid);
2867                if (mBadProcesses.get(info.processName, info.uid) != null) {
2868                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2869                            UserHandle.getUserId(info.uid), info.uid,
2870                            info.processName);
2871                    mBadProcesses.remove(info.processName, info.uid);
2872                    if (app != null) {
2873                        app.bad = false;
2874                    }
2875                }
2876            }
2877        }
2878
2879        if (app == null) {
2880            app = newProcessRecordLocked(info, processName, isolated);
2881            if (app == null) {
2882                Slog.w(TAG, "Failed making new process record for "
2883                        + processName + "/" + info.uid + " isolated=" + isolated);
2884                return null;
2885            }
2886            mProcessNames.put(processName, app.uid, app);
2887            if (isolated) {
2888                mIsolatedProcesses.put(app.uid, app);
2889            }
2890        } else {
2891            // If this is a new package in the process, add the package to the list
2892            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2893        }
2894
2895        // If the system is not ready yet, then hold off on starting this
2896        // process until it is.
2897        if (!mProcessesReady
2898                && !isAllowedWhileBooting(info)
2899                && !allowWhileBooting) {
2900            if (!mProcessesOnHold.contains(app)) {
2901                mProcessesOnHold.add(app);
2902            }
2903            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2904            return app;
2905        }
2906
2907        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2908        return (app.pid != 0) ? app : null;
2909    }
2910
2911    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2912        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2913    }
2914
2915    private final void startProcessLocked(ProcessRecord app,
2916            String hostingType, String hostingNameStr, String abiOverride) {
2917        if (app.pid > 0 && app.pid != MY_PID) {
2918            synchronized (mPidsSelfLocked) {
2919                mPidsSelfLocked.remove(app.pid);
2920                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2921            }
2922            app.setPid(0);
2923        }
2924
2925        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2926                "startProcessLocked removing on hold: " + app);
2927        mProcessesOnHold.remove(app);
2928
2929        updateCpuStats();
2930
2931        try {
2932            int uid = app.uid;
2933
2934            int[] gids = null;
2935            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2936            if (!app.isolated) {
2937                int[] permGids = null;
2938                try {
2939                    final PackageManager pm = mContext.getPackageManager();
2940                    permGids = pm.getPackageGids(app.info.packageName);
2941
2942                    if (Environment.isExternalStorageEmulated()) {
2943                        if (pm.checkPermission(
2944                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2945                                app.info.packageName) == PERMISSION_GRANTED) {
2946                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2947                        } else {
2948                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2949                        }
2950                    }
2951                } catch (PackageManager.NameNotFoundException e) {
2952                    Slog.w(TAG, "Unable to retrieve gids", e);
2953                }
2954
2955                /*
2956                 * Add shared application and profile GIDs so applications can share some
2957                 * resources like shared libraries and access user-wide resources
2958                 */
2959                if (permGids == null) {
2960                    gids = new int[2];
2961                } else {
2962                    gids = new int[permGids.length + 2];
2963                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2964                }
2965                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2966                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2967            }
2968            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2969                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2970                        && mTopComponent != null
2971                        && app.processName.equals(mTopComponent.getPackageName())) {
2972                    uid = 0;
2973                }
2974                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2975                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2976                    uid = 0;
2977                }
2978            }
2979            int debugFlags = 0;
2980            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2981                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2982                // Also turn on CheckJNI for debuggable apps. It's quite
2983                // awkward to turn on otherwise.
2984                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2985            }
2986            // Run the app in safe mode if its manifest requests so or the
2987            // system is booted in safe mode.
2988            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2989                mSafeMode == true) {
2990                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2991            }
2992            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2993                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2994            }
2995            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2996                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2997            }
2998            if ("1".equals(SystemProperties.get("debug.assert"))) {
2999                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3000            }
3001
3002            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3003            if (requiredAbi == null) {
3004                requiredAbi = Build.SUPPORTED_ABIS[0];
3005            }
3006
3007            // Start the process.  It will either succeed and return a result containing
3008            // the PID of the new process, or else throw a RuntimeException.
3009            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3010                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3011                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3012
3013            if (app.isolated) {
3014                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3015            }
3016            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3017
3018            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3019                    UserHandle.getUserId(uid), startResult.pid, uid,
3020                    app.processName, hostingType,
3021                    hostingNameStr != null ? hostingNameStr : "");
3022
3023            if (app.persistent) {
3024                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3025            }
3026
3027            StringBuilder buf = mStringBuilder;
3028            buf.setLength(0);
3029            buf.append("Start proc ");
3030            buf.append(app.processName);
3031            buf.append(" for ");
3032            buf.append(hostingType);
3033            if (hostingNameStr != null) {
3034                buf.append(" ");
3035                buf.append(hostingNameStr);
3036            }
3037            buf.append(": pid=");
3038            buf.append(startResult.pid);
3039            buf.append(" uid=");
3040            buf.append(uid);
3041            buf.append(" gids={");
3042            if (gids != null) {
3043                for (int gi=0; gi<gids.length; gi++) {
3044                    if (gi != 0) buf.append(", ");
3045                    buf.append(gids[gi]);
3046
3047                }
3048            }
3049            buf.append("}");
3050            if (requiredAbi != null) {
3051                buf.append(" abi=");
3052                buf.append(requiredAbi);
3053            }
3054            Slog.i(TAG, buf.toString());
3055            app.setPid(startResult.pid);
3056            app.usingWrapper = startResult.usingWrapper;
3057            app.removed = false;
3058            app.killedByAm = false;
3059            synchronized (mPidsSelfLocked) {
3060                this.mPidsSelfLocked.put(startResult.pid, app);
3061                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3062                msg.obj = app;
3063                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3064                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3065            }
3066        } catch (RuntimeException e) {
3067            // XXX do better error recovery.
3068            app.setPid(0);
3069            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3070            if (app.isolated) {
3071                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3072            }
3073            Slog.e(TAG, "Failure starting process " + app.processName, e);
3074        }
3075    }
3076
3077    void updateUsageStats(ActivityRecord component, boolean resumed) {
3078        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3079        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3080        if (resumed) {
3081            if (mUsageStatsService != null) {
3082                mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(),
3083                        UsageStats.Event.MOVE_TO_FOREGROUND);
3084            }
3085            synchronized (stats) {
3086                stats.noteActivityResumedLocked(component.app.uid);
3087            }
3088        } else {
3089            if (mUsageStatsService != null) {
3090                mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(),
3091                        UsageStats.Event.MOVE_TO_BACKGROUND);
3092            }
3093            synchronized (stats) {
3094                stats.noteActivityPausedLocked(component.app.uid);
3095            }
3096        }
3097    }
3098
3099    Intent getHomeIntent() {
3100        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3101        intent.setComponent(mTopComponent);
3102        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3103            intent.addCategory(Intent.CATEGORY_HOME);
3104        }
3105        return intent;
3106    }
3107
3108    boolean startHomeActivityLocked(int userId) {
3109        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3110                && mTopAction == null) {
3111            // We are running in factory test mode, but unable to find
3112            // the factory test app, so just sit around displaying the
3113            // error message and don't try to start anything.
3114            return false;
3115        }
3116        Intent intent = getHomeIntent();
3117        ActivityInfo aInfo =
3118            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3119        if (aInfo != null) {
3120            intent.setComponent(new ComponentName(
3121                    aInfo.applicationInfo.packageName, aInfo.name));
3122            // Don't do this if the home app is currently being
3123            // instrumented.
3124            aInfo = new ActivityInfo(aInfo);
3125            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3126            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3127                    aInfo.applicationInfo.uid, true);
3128            if (app == null || app.instrumentationClass == null) {
3129                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3130                mStackSupervisor.startHomeActivity(intent, aInfo);
3131            }
3132        }
3133
3134        return true;
3135    }
3136
3137    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3138        ActivityInfo ai = null;
3139        ComponentName comp = intent.getComponent();
3140        try {
3141            if (comp != null) {
3142                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3143            } else {
3144                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3145                        intent,
3146                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3147                            flags, userId);
3148
3149                if (info != null) {
3150                    ai = info.activityInfo;
3151                }
3152            }
3153        } catch (RemoteException e) {
3154            // ignore
3155        }
3156
3157        return ai;
3158    }
3159
3160    /**
3161     * Starts the "new version setup screen" if appropriate.
3162     */
3163    void startSetupActivityLocked() {
3164        // Only do this once per boot.
3165        if (mCheckedForSetup) {
3166            return;
3167        }
3168
3169        // We will show this screen if the current one is a different
3170        // version than the last one shown, and we are not running in
3171        // low-level factory test mode.
3172        final ContentResolver resolver = mContext.getContentResolver();
3173        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3174                Settings.Global.getInt(resolver,
3175                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3176            mCheckedForSetup = true;
3177
3178            // See if we should be showing the platform update setup UI.
3179            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3180            List<ResolveInfo> ris = mContext.getPackageManager()
3181                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3182
3183            // We don't allow third party apps to replace this.
3184            ResolveInfo ri = null;
3185            for (int i=0; ris != null && i<ris.size(); i++) {
3186                if ((ris.get(i).activityInfo.applicationInfo.flags
3187                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3188                    ri = ris.get(i);
3189                    break;
3190                }
3191            }
3192
3193            if (ri != null) {
3194                String vers = ri.activityInfo.metaData != null
3195                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3196                        : null;
3197                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3198                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3199                            Intent.METADATA_SETUP_VERSION);
3200                }
3201                String lastVers = Settings.Secure.getString(
3202                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3203                if (vers != null && !vers.equals(lastVers)) {
3204                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3205                    intent.setComponent(new ComponentName(
3206                            ri.activityInfo.packageName, ri.activityInfo.name));
3207                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3208                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3209                }
3210            }
3211        }
3212    }
3213
3214    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3215        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3216    }
3217
3218    void enforceNotIsolatedCaller(String caller) {
3219        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3220            throw new SecurityException("Isolated process not allowed to call " + caller);
3221        }
3222    }
3223
3224    @Override
3225    public int getFrontActivityScreenCompatMode() {
3226        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3227        synchronized (this) {
3228            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3229        }
3230    }
3231
3232    @Override
3233    public void setFrontActivityScreenCompatMode(int mode) {
3234        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3235                "setFrontActivityScreenCompatMode");
3236        synchronized (this) {
3237            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3238        }
3239    }
3240
3241    @Override
3242    public int getPackageScreenCompatMode(String packageName) {
3243        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3244        synchronized (this) {
3245            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3246        }
3247    }
3248
3249    @Override
3250    public void setPackageScreenCompatMode(String packageName, int mode) {
3251        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3252                "setPackageScreenCompatMode");
3253        synchronized (this) {
3254            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3255        }
3256    }
3257
3258    @Override
3259    public boolean getPackageAskScreenCompat(String packageName) {
3260        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3261        synchronized (this) {
3262            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3263        }
3264    }
3265
3266    @Override
3267    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3268        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3269                "setPackageAskScreenCompat");
3270        synchronized (this) {
3271            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3272        }
3273    }
3274
3275    private void dispatchProcessesChanged() {
3276        int N;
3277        synchronized (this) {
3278            N = mPendingProcessChanges.size();
3279            if (mActiveProcessChanges.length < N) {
3280                mActiveProcessChanges = new ProcessChangeItem[N];
3281            }
3282            mPendingProcessChanges.toArray(mActiveProcessChanges);
3283            mAvailProcessChanges.addAll(mPendingProcessChanges);
3284            mPendingProcessChanges.clear();
3285            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3286        }
3287
3288        int i = mProcessObservers.beginBroadcast();
3289        while (i > 0) {
3290            i--;
3291            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3292            if (observer != null) {
3293                try {
3294                    for (int j=0; j<N; j++) {
3295                        ProcessChangeItem item = mActiveProcessChanges[j];
3296                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3297                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3298                                    + item.pid + " uid=" + item.uid + ": "
3299                                    + item.foregroundActivities);
3300                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3301                                    item.foregroundActivities);
3302                        }
3303                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3304                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3305                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3306                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3307                        }
3308                    }
3309                } catch (RemoteException e) {
3310                }
3311            }
3312        }
3313        mProcessObservers.finishBroadcast();
3314    }
3315
3316    private void dispatchProcessDied(int pid, int uid) {
3317        int i = mProcessObservers.beginBroadcast();
3318        while (i > 0) {
3319            i--;
3320            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3321            if (observer != null) {
3322                try {
3323                    observer.onProcessDied(pid, uid);
3324                } catch (RemoteException e) {
3325                }
3326            }
3327        }
3328        mProcessObservers.finishBroadcast();
3329    }
3330
3331    @Override
3332    public final int startActivity(IApplicationThread caller, String callingPackage,
3333            Intent intent, String resolvedType, IBinder resultTo,
3334            String resultWho, int requestCode, int startFlags,
3335            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3336        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3337                resultWho, requestCode,
3338                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3339    }
3340
3341    @Override
3342    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3343            Intent intent, String resolvedType, IBinder resultTo,
3344            String resultWho, int requestCode, int startFlags,
3345            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3346        enforceNotIsolatedCaller("startActivity");
3347        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3348                false, ALLOW_FULL_ONLY, "startActivity", null);
3349        // TODO: Switch to user app stacks here.
3350        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3351                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3352                null, null, options, userId, null);
3353    }
3354
3355    @Override
3356    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3357            Intent intent, String resolvedType, IBinder resultTo,
3358            String resultWho, int requestCode, int startFlags, String profileFile,
3359            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3360        enforceNotIsolatedCaller("startActivityAndWait");
3361        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3362                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3363        WaitResult res = new WaitResult();
3364        // TODO: Switch to user app stacks here.
3365        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3366                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3367                res, null, options, userId, null);
3368        return res;
3369    }
3370
3371    @Override
3372    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3373            Intent intent, String resolvedType, IBinder resultTo,
3374            String resultWho, int requestCode, int startFlags, Configuration config,
3375            Bundle options, int userId) {
3376        enforceNotIsolatedCaller("startActivityWithConfig");
3377        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3378                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3379        // TODO: Switch to user app stacks here.
3380        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3381                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3382                null, null, null, config, options, userId, null);
3383        return ret;
3384    }
3385
3386    @Override
3387    public int startActivityIntentSender(IApplicationThread caller,
3388            IntentSender intent, Intent fillInIntent, String resolvedType,
3389            IBinder resultTo, String resultWho, int requestCode,
3390            int flagsMask, int flagsValues, Bundle options) {
3391        enforceNotIsolatedCaller("startActivityIntentSender");
3392        // Refuse possible leaked file descriptors
3393        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3394            throw new IllegalArgumentException("File descriptors passed in Intent");
3395        }
3396
3397        IIntentSender sender = intent.getTarget();
3398        if (!(sender instanceof PendingIntentRecord)) {
3399            throw new IllegalArgumentException("Bad PendingIntent object");
3400        }
3401
3402        PendingIntentRecord pir = (PendingIntentRecord)sender;
3403
3404        synchronized (this) {
3405            // If this is coming from the currently resumed activity, it is
3406            // effectively saying that app switches are allowed at this point.
3407            final ActivityStack stack = getFocusedStack();
3408            if (stack.mResumedActivity != null &&
3409                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3410                mAppSwitchesAllowedTime = 0;
3411            }
3412        }
3413        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3414                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3415        return ret;
3416    }
3417
3418    @Override
3419    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3420            Intent intent, String resolvedType, IVoiceInteractionSession session,
3421            IVoiceInteractor interactor, int startFlags, String profileFile,
3422            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3423        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3424                != PackageManager.PERMISSION_GRANTED) {
3425            String msg = "Permission Denial: startVoiceActivity() from pid="
3426                    + Binder.getCallingPid()
3427                    + ", uid=" + Binder.getCallingUid()
3428                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3429            Slog.w(TAG, msg);
3430            throw new SecurityException(msg);
3431        }
3432        if (session == null || interactor == null) {
3433            throw new NullPointerException("null session or interactor");
3434        }
3435        userId = handleIncomingUser(callingPid, callingUid, userId,
3436                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3437        // TODO: Switch to user app stacks here.
3438        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3439                resolvedType, session, interactor, null, null, 0, startFlags,
3440                profileFile, profileFd, null, null, options, userId, null);
3441    }
3442
3443    @Override
3444    public boolean startNextMatchingActivity(IBinder callingActivity,
3445            Intent intent, Bundle options) {
3446        // Refuse possible leaked file descriptors
3447        if (intent != null && intent.hasFileDescriptors() == true) {
3448            throw new IllegalArgumentException("File descriptors passed in Intent");
3449        }
3450
3451        synchronized (this) {
3452            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3453            if (r == null) {
3454                ActivityOptions.abort(options);
3455                return false;
3456            }
3457            if (r.app == null || r.app.thread == null) {
3458                // The caller is not running...  d'oh!
3459                ActivityOptions.abort(options);
3460                return false;
3461            }
3462            intent = new Intent(intent);
3463            // The caller is not allowed to change the data.
3464            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3465            // And we are resetting to find the next component...
3466            intent.setComponent(null);
3467
3468            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3469
3470            ActivityInfo aInfo = null;
3471            try {
3472                List<ResolveInfo> resolves =
3473                    AppGlobals.getPackageManager().queryIntentActivities(
3474                            intent, r.resolvedType,
3475                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3476                            UserHandle.getCallingUserId());
3477
3478                // Look for the original activity in the list...
3479                final int N = resolves != null ? resolves.size() : 0;
3480                for (int i=0; i<N; i++) {
3481                    ResolveInfo rInfo = resolves.get(i);
3482                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3483                            && rInfo.activityInfo.name.equals(r.info.name)) {
3484                        // We found the current one...  the next matching is
3485                        // after it.
3486                        i++;
3487                        if (i<N) {
3488                            aInfo = resolves.get(i).activityInfo;
3489                        }
3490                        if (debug) {
3491                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3492                                    + "/" + r.info.name);
3493                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3494                                    + "/" + aInfo.name);
3495                        }
3496                        break;
3497                    }
3498                }
3499            } catch (RemoteException e) {
3500            }
3501
3502            if (aInfo == null) {
3503                // Nobody who is next!
3504                ActivityOptions.abort(options);
3505                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3506                return false;
3507            }
3508
3509            intent.setComponent(new ComponentName(
3510                    aInfo.applicationInfo.packageName, aInfo.name));
3511            intent.setFlags(intent.getFlags()&~(
3512                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3513                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3514                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3515                    Intent.FLAG_ACTIVITY_NEW_TASK));
3516
3517            // Okay now we need to start the new activity, replacing the
3518            // currently running activity.  This is a little tricky because
3519            // we want to start the new one as if the current one is finished,
3520            // but not finish the current one first so that there is no flicker.
3521            // And thus...
3522            final boolean wasFinishing = r.finishing;
3523            r.finishing = true;
3524
3525            // Propagate reply information over to the new activity.
3526            final ActivityRecord resultTo = r.resultTo;
3527            final String resultWho = r.resultWho;
3528            final int requestCode = r.requestCode;
3529            r.resultTo = null;
3530            if (resultTo != null) {
3531                resultTo.removeResultsLocked(r, resultWho, requestCode);
3532            }
3533
3534            final long origId = Binder.clearCallingIdentity();
3535            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3536                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3537                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3538                    options, false, null, null);
3539            Binder.restoreCallingIdentity(origId);
3540
3541            r.finishing = wasFinishing;
3542            if (res != ActivityManager.START_SUCCESS) {
3543                return false;
3544            }
3545            return true;
3546        }
3547    }
3548
3549    @Override
3550    public final int startActivityFromRecents(int taskId, Bundle options) {
3551        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3552            String msg = "Permission Denial: startActivityFromRecents called without " +
3553                    START_TASKS_FROM_RECENTS;
3554            Slog.w(TAG, msg);
3555            throw new SecurityException(msg);
3556        }
3557        final int callingUid;
3558        final String callingPackage;
3559        final Intent intent;
3560        final int userId;
3561        synchronized (this) {
3562            final TaskRecord task = recentTaskForIdLocked(taskId);
3563            if (task == null) {
3564                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3565            }
3566            callingUid = task.mCallingUid;
3567            callingPackage = task.mCallingPackage;
3568            intent = task.intent;
3569            userId = task.userId;
3570        }
3571        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3572                options, userId, null);
3573    }
3574
3575    final int startActivityInPackage(int uid, String callingPackage,
3576            Intent intent, String resolvedType, IBinder resultTo,
3577            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3578                    IActivityContainer container) {
3579
3580        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3581                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3582
3583        // TODO: Switch to user app stacks here.
3584        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3585                null, null, resultTo, resultWho, requestCode, startFlags,
3586                null, null, null, null, options, userId, container);
3587        return ret;
3588    }
3589
3590    @Override
3591    public final int startActivities(IApplicationThread caller, String callingPackage,
3592            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3593            int userId) {
3594        enforceNotIsolatedCaller("startActivities");
3595        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3596                false, ALLOW_FULL_ONLY, "startActivity", null);
3597        // TODO: Switch to user app stacks here.
3598        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3599                resolvedTypes, resultTo, options, userId);
3600        return ret;
3601    }
3602
3603    final int startActivitiesInPackage(int uid, String callingPackage,
3604            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3605            Bundle options, int userId) {
3606
3607        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3608                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3609        // TODO: Switch to user app stacks here.
3610        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3611                resultTo, options, userId);
3612        return ret;
3613    }
3614
3615    final void addRecentTaskLocked(TaskRecord task) {
3616        int N = mRecentTasks.size();
3617        // Quick case: check if the top-most recent task is the same.
3618        if (N > 0 && mRecentTasks.get(0) == task) {
3619            return;
3620        }
3621        // Another quick case: never add voice sessions.
3622        if (task.voiceSession != null) {
3623            return;
3624        }
3625        // Remove any existing entries that are the same kind of task.
3626        final Intent intent = task.intent;
3627        final boolean document = intent != null && intent.isDocument();
3628        final ComponentName comp = intent.getComponent();
3629
3630        int maxRecents = task.maxRecents - 1;
3631        for (int i=0; i<N; i++) {
3632            final TaskRecord tr = mRecentTasks.get(i);
3633            if (task != tr) {
3634                if (task.userId != tr.userId) {
3635                    continue;
3636                }
3637                if (i > MAX_RECENT_BITMAPS) {
3638                    tr.freeLastThumbnail();
3639                }
3640                final Intent trIntent = tr.intent;
3641                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3642                    (intent == null || !intent.filterEquals(trIntent))) {
3643                    continue;
3644                }
3645                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3646                if (document && trIsDocument) {
3647                    // These are the same document activity (not necessarily the same doc).
3648                    if (maxRecents > 0) {
3649                        --maxRecents;
3650                        continue;
3651                    }
3652                    // Hit the maximum number of documents for this task. Fall through
3653                    // and remove this document from recents.
3654                } else if (document || trIsDocument) {
3655                    // Only one of these is a document. Not the droid we're looking for.
3656                    continue;
3657                }
3658            }
3659
3660            // Either task and tr are the same or, their affinities match or their intents match
3661            // and neither of them is a document, or they are documents using the same activity
3662            // and their maxRecents has been reached.
3663            tr.disposeThumbnail();
3664            mRecentTasks.remove(i);
3665            if (task != tr) {
3666                tr.closeRecentsChain();
3667            }
3668            i--;
3669            N--;
3670            if (task.intent == null) {
3671                // If the new recent task we are adding is not fully
3672                // specified, then replace it with the existing recent task.
3673                task = tr;
3674            }
3675            mTaskPersister.notify(tr, false);
3676        }
3677        if (N >= MAX_RECENT_TASKS) {
3678            final TaskRecord tr = mRecentTasks.remove(N - 1);
3679            tr.disposeThumbnail();
3680            tr.closeRecentsChain();
3681        }
3682        mRecentTasks.add(0, task);
3683    }
3684
3685    @Override
3686    public void reportActivityFullyDrawn(IBinder token) {
3687        synchronized (this) {
3688            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3689            if (r == null) {
3690                return;
3691            }
3692            r.reportFullyDrawnLocked();
3693        }
3694    }
3695
3696    @Override
3697    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3698        synchronized (this) {
3699            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3700            if (r == null) {
3701                return;
3702            }
3703            final long origId = Binder.clearCallingIdentity();
3704            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3705            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3706                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3707            if (config != null) {
3708                r.frozenBeforeDestroy = true;
3709                if (!updateConfigurationLocked(config, r, false, false)) {
3710                    mStackSupervisor.resumeTopActivitiesLocked();
3711                }
3712            }
3713            Binder.restoreCallingIdentity(origId);
3714        }
3715    }
3716
3717    @Override
3718    public int getRequestedOrientation(IBinder token) {
3719        synchronized (this) {
3720            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3721            if (r == null) {
3722                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3723            }
3724            return mWindowManager.getAppOrientation(r.appToken);
3725        }
3726    }
3727
3728    /**
3729     * This is the internal entry point for handling Activity.finish().
3730     *
3731     * @param token The Binder token referencing the Activity we want to finish.
3732     * @param resultCode Result code, if any, from this Activity.
3733     * @param resultData Result data (Intent), if any, from this Activity.
3734     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3735     *            the root Activity in the task.
3736     *
3737     * @return Returns true if the activity successfully finished, or false if it is still running.
3738     */
3739    @Override
3740    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3741            boolean finishTask) {
3742        // Refuse possible leaked file descriptors
3743        if (resultData != null && resultData.hasFileDescriptors() == true) {
3744            throw new IllegalArgumentException("File descriptors passed in Intent");
3745        }
3746
3747        synchronized(this) {
3748            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3749            if (r == null) {
3750                return true;
3751            }
3752            // Keep track of the root activity of the task before we finish it
3753            TaskRecord tr = r.task;
3754            ActivityRecord rootR = tr.getRootActivity();
3755            // Do not allow task to finish in Lock Task mode.
3756            if (tr == mStackSupervisor.mLockTaskModeTask) {
3757                if (rootR == r) {
3758                    mStackSupervisor.showLockTaskToast();
3759                    return false;
3760                }
3761            }
3762            if (mController != null) {
3763                // Find the first activity that is not finishing.
3764                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3765                if (next != null) {
3766                    // ask watcher if this is allowed
3767                    boolean resumeOK = true;
3768                    try {
3769                        resumeOK = mController.activityResuming(next.packageName);
3770                    } catch (RemoteException e) {
3771                        mController = null;
3772                        Watchdog.getInstance().setActivityController(null);
3773                    }
3774
3775                    if (!resumeOK) {
3776                        return false;
3777                    }
3778                }
3779            }
3780            final long origId = Binder.clearCallingIdentity();
3781            try {
3782                boolean res;
3783                if (finishTask && r == rootR) {
3784                    // If requested, remove the task that is associated to this activity only if it
3785                    // was the root activity in the task.  The result code and data is ignored because
3786                    // we don't support returning them across task boundaries.
3787                    res = removeTaskByIdLocked(tr.taskId, 0);
3788                } else {
3789                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3790                            resultData, "app-request", true);
3791                }
3792                return res;
3793            } finally {
3794                Binder.restoreCallingIdentity(origId);
3795            }
3796        }
3797    }
3798
3799    @Override
3800    public final void finishHeavyWeightApp() {
3801        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3802                != PackageManager.PERMISSION_GRANTED) {
3803            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3804                    + Binder.getCallingPid()
3805                    + ", uid=" + Binder.getCallingUid()
3806                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3807            Slog.w(TAG, msg);
3808            throw new SecurityException(msg);
3809        }
3810
3811        synchronized(this) {
3812            if (mHeavyWeightProcess == null) {
3813                return;
3814            }
3815
3816            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3817                    mHeavyWeightProcess.activities);
3818            for (int i=0; i<activities.size(); i++) {
3819                ActivityRecord r = activities.get(i);
3820                if (!r.finishing) {
3821                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3822                            null, "finish-heavy", true);
3823                }
3824            }
3825
3826            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3827                    mHeavyWeightProcess.userId, 0));
3828            mHeavyWeightProcess = null;
3829        }
3830    }
3831
3832    @Override
3833    public void crashApplication(int uid, int initialPid, String packageName,
3834            String message) {
3835        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3836                != PackageManager.PERMISSION_GRANTED) {
3837            String msg = "Permission Denial: crashApplication() from pid="
3838                    + Binder.getCallingPid()
3839                    + ", uid=" + Binder.getCallingUid()
3840                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3841            Slog.w(TAG, msg);
3842            throw new SecurityException(msg);
3843        }
3844
3845        synchronized(this) {
3846            ProcessRecord proc = null;
3847
3848            // Figure out which process to kill.  We don't trust that initialPid
3849            // still has any relation to current pids, so must scan through the
3850            // list.
3851            synchronized (mPidsSelfLocked) {
3852                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3853                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3854                    if (p.uid != uid) {
3855                        continue;
3856                    }
3857                    if (p.pid == initialPid) {
3858                        proc = p;
3859                        break;
3860                    }
3861                    if (p.pkgList.containsKey(packageName)) {
3862                        proc = p;
3863                    }
3864                }
3865            }
3866
3867            if (proc == null) {
3868                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3869                        + " initialPid=" + initialPid
3870                        + " packageName=" + packageName);
3871                return;
3872            }
3873
3874            if (proc.thread != null) {
3875                if (proc.pid == Process.myPid()) {
3876                    Log.w(TAG, "crashApplication: trying to crash self!");
3877                    return;
3878                }
3879                long ident = Binder.clearCallingIdentity();
3880                try {
3881                    proc.thread.scheduleCrash(message);
3882                } catch (RemoteException e) {
3883                }
3884                Binder.restoreCallingIdentity(ident);
3885            }
3886        }
3887    }
3888
3889    @Override
3890    public final void finishSubActivity(IBinder token, String resultWho,
3891            int requestCode) {
3892        synchronized(this) {
3893            final long origId = Binder.clearCallingIdentity();
3894            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3895            if (r != null) {
3896                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3897            }
3898            Binder.restoreCallingIdentity(origId);
3899        }
3900    }
3901
3902    @Override
3903    public boolean finishActivityAffinity(IBinder token) {
3904        synchronized(this) {
3905            final long origId = Binder.clearCallingIdentity();
3906            try {
3907                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3908
3909                ActivityRecord rootR = r.task.getRootActivity();
3910                // Do not allow task to finish in Lock Task mode.
3911                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3912                    if (rootR == r) {
3913                        mStackSupervisor.showLockTaskToast();
3914                        return false;
3915                    }
3916                }
3917                boolean res = false;
3918                if (r != null) {
3919                    res = r.task.stack.finishActivityAffinityLocked(r);
3920                }
3921                return res;
3922            } finally {
3923                Binder.restoreCallingIdentity(origId);
3924            }
3925        }
3926    }
3927
3928    @Override
3929    public void finishVoiceTask(IVoiceInteractionSession session) {
3930        synchronized(this) {
3931            final long origId = Binder.clearCallingIdentity();
3932            try {
3933                mStackSupervisor.finishVoiceTask(session);
3934            } finally {
3935                Binder.restoreCallingIdentity(origId);
3936            }
3937        }
3938
3939    }
3940
3941    @Override
3942    public boolean willActivityBeVisible(IBinder token) {
3943        synchronized(this) {
3944            ActivityStack stack = ActivityRecord.getStackLocked(token);
3945            if (stack != null) {
3946                return stack.willActivityBeVisibleLocked(token);
3947            }
3948            return false;
3949        }
3950    }
3951
3952    @Override
3953    public void overridePendingTransition(IBinder token, String packageName,
3954            int enterAnim, int exitAnim) {
3955        synchronized(this) {
3956            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3957            if (self == null) {
3958                return;
3959            }
3960
3961            final long origId = Binder.clearCallingIdentity();
3962
3963            if (self.state == ActivityState.RESUMED
3964                    || self.state == ActivityState.PAUSING) {
3965                mWindowManager.overridePendingAppTransition(packageName,
3966                        enterAnim, exitAnim, null);
3967            }
3968
3969            Binder.restoreCallingIdentity(origId);
3970        }
3971    }
3972
3973    /**
3974     * Main function for removing an existing process from the activity manager
3975     * as a result of that process going away.  Clears out all connections
3976     * to the process.
3977     */
3978    private final void handleAppDiedLocked(ProcessRecord app,
3979            boolean restarting, boolean allowRestart) {
3980        int pid = app.pid;
3981        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3982        if (!restarting) {
3983            removeLruProcessLocked(app);
3984            if (pid > 0) {
3985                ProcessList.remove(pid);
3986            }
3987        }
3988
3989        if (mProfileProc == app) {
3990            clearProfilerLocked();
3991        }
3992
3993        // Remove this application's activities from active lists.
3994        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3995
3996        app.activities.clear();
3997
3998        if (app.instrumentationClass != null) {
3999            Slog.w(TAG, "Crash of app " + app.processName
4000                  + " running instrumentation " + app.instrumentationClass);
4001            Bundle info = new Bundle();
4002            info.putString("shortMsg", "Process crashed.");
4003            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4004        }
4005
4006        if (!restarting) {
4007            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4008                // If there was nothing to resume, and we are not already
4009                // restarting this process, but there is a visible activity that
4010                // is hosted by the process...  then make sure all visible
4011                // activities are running, taking care of restarting this
4012                // process.
4013                if (hasVisibleActivities) {
4014                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4015                }
4016            }
4017        }
4018    }
4019
4020    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4021        IBinder threadBinder = thread.asBinder();
4022        // Find the application record.
4023        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4024            ProcessRecord rec = mLruProcesses.get(i);
4025            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4026                return i;
4027            }
4028        }
4029        return -1;
4030    }
4031
4032    final ProcessRecord getRecordForAppLocked(
4033            IApplicationThread thread) {
4034        if (thread == null) {
4035            return null;
4036        }
4037
4038        int appIndex = getLRURecordIndexForAppLocked(thread);
4039        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4040    }
4041
4042    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4043        // If there are no longer any background processes running,
4044        // and the app that died was not running instrumentation,
4045        // then tell everyone we are now low on memory.
4046        boolean haveBg = false;
4047        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4048            ProcessRecord rec = mLruProcesses.get(i);
4049            if (rec.thread != null
4050                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4051                haveBg = true;
4052                break;
4053            }
4054        }
4055
4056        if (!haveBg) {
4057            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4058            if (doReport) {
4059                long now = SystemClock.uptimeMillis();
4060                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4061                    doReport = false;
4062                } else {
4063                    mLastMemUsageReportTime = now;
4064                }
4065            }
4066            final ArrayList<ProcessMemInfo> memInfos
4067                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4068            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4069            long now = SystemClock.uptimeMillis();
4070            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4071                ProcessRecord rec = mLruProcesses.get(i);
4072                if (rec == dyingProc || rec.thread == null) {
4073                    continue;
4074                }
4075                if (doReport) {
4076                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4077                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4078                }
4079                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4080                    // The low memory report is overriding any current
4081                    // state for a GC request.  Make sure to do
4082                    // heavy/important/visible/foreground processes first.
4083                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4084                        rec.lastRequestedGc = 0;
4085                    } else {
4086                        rec.lastRequestedGc = rec.lastLowMemory;
4087                    }
4088                    rec.reportLowMemory = true;
4089                    rec.lastLowMemory = now;
4090                    mProcessesToGc.remove(rec);
4091                    addProcessToGcListLocked(rec);
4092                }
4093            }
4094            if (doReport) {
4095                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4096                mHandler.sendMessage(msg);
4097            }
4098            scheduleAppGcsLocked();
4099        }
4100    }
4101
4102    final void appDiedLocked(ProcessRecord app, int pid,
4103            IApplicationThread thread) {
4104
4105        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4106        synchronized (stats) {
4107            stats.noteProcessDiedLocked(app.info.uid, pid);
4108        }
4109
4110        Process.killProcessGroup(app.info.uid, pid);
4111
4112        // Clean up already done if the process has been re-started.
4113        if (app.pid == pid && app.thread != null &&
4114                app.thread.asBinder() == thread.asBinder()) {
4115            boolean doLowMem = app.instrumentationClass == null;
4116            boolean doOomAdj = doLowMem;
4117            if (!app.killedByAm) {
4118                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4119                        + ") has died.");
4120                mAllowLowerMemLevel = true;
4121            } else {
4122                // Note that we always want to do oom adj to update our state with the
4123                // new number of procs.
4124                mAllowLowerMemLevel = false;
4125                doLowMem = false;
4126            }
4127            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4128            if (DEBUG_CLEANUP) Slog.v(
4129                TAG, "Dying app: " + app + ", pid: " + pid
4130                + ", thread: " + thread.asBinder());
4131            handleAppDiedLocked(app, false, true);
4132
4133            if (doOomAdj) {
4134                updateOomAdjLocked();
4135            }
4136            if (doLowMem) {
4137                doLowMemReportIfNeededLocked(app);
4138            }
4139        } else if (app.pid != pid) {
4140            // A new process has already been started.
4141            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4142                    + ") has died and restarted (pid " + app.pid + ").");
4143            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4144        } else if (DEBUG_PROCESSES) {
4145            Slog.d(TAG, "Received spurious death notification for thread "
4146                    + thread.asBinder());
4147        }
4148    }
4149
4150    /**
4151     * If a stack trace dump file is configured, dump process stack traces.
4152     * @param clearTraces causes the dump file to be erased prior to the new
4153     *    traces being written, if true; when false, the new traces will be
4154     *    appended to any existing file content.
4155     * @param firstPids of dalvik VM processes to dump stack traces for first
4156     * @param lastPids of dalvik VM processes to dump stack traces for last
4157     * @param nativeProcs optional list of native process names to dump stack crawls
4158     * @return file containing stack traces, or null if no dump file is configured
4159     */
4160    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4161            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4162        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4163        if (tracesPath == null || tracesPath.length() == 0) {
4164            return null;
4165        }
4166
4167        File tracesFile = new File(tracesPath);
4168        try {
4169            File tracesDir = tracesFile.getParentFile();
4170            if (!tracesDir.exists()) {
4171                tracesFile.mkdirs();
4172                if (!SELinux.restorecon(tracesDir)) {
4173                    return null;
4174                }
4175            }
4176            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4177
4178            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4179            tracesFile.createNewFile();
4180            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4181        } catch (IOException e) {
4182            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4183            return null;
4184        }
4185
4186        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4187        return tracesFile;
4188    }
4189
4190    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4191            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4192        // Use a FileObserver to detect when traces finish writing.
4193        // The order of traces is considered important to maintain for legibility.
4194        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4195            @Override
4196            public synchronized void onEvent(int event, String path) { notify(); }
4197        };
4198
4199        try {
4200            observer.startWatching();
4201
4202            // First collect all of the stacks of the most important pids.
4203            if (firstPids != null) {
4204                try {
4205                    int num = firstPids.size();
4206                    for (int i = 0; i < num; i++) {
4207                        synchronized (observer) {
4208                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4209                            observer.wait(200);  // Wait for write-close, give up after 200msec
4210                        }
4211                    }
4212                } catch (InterruptedException e) {
4213                    Log.wtf(TAG, e);
4214                }
4215            }
4216
4217            // Next collect the stacks of the native pids
4218            if (nativeProcs != null) {
4219                int[] pids = Process.getPidsForCommands(nativeProcs);
4220                if (pids != null) {
4221                    for (int pid : pids) {
4222                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4223                    }
4224                }
4225            }
4226
4227            // Lastly, measure CPU usage.
4228            if (processCpuTracker != null) {
4229                processCpuTracker.init();
4230                System.gc();
4231                processCpuTracker.update();
4232                try {
4233                    synchronized (processCpuTracker) {
4234                        processCpuTracker.wait(500); // measure over 1/2 second.
4235                    }
4236                } catch (InterruptedException e) {
4237                }
4238                processCpuTracker.update();
4239
4240                // We'll take the stack crawls of just the top apps using CPU.
4241                final int N = processCpuTracker.countWorkingStats();
4242                int numProcs = 0;
4243                for (int i=0; i<N && numProcs<5; i++) {
4244                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4245                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4246                        numProcs++;
4247                        try {
4248                            synchronized (observer) {
4249                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4250                                observer.wait(200);  // Wait for write-close, give up after 200msec
4251                            }
4252                        } catch (InterruptedException e) {
4253                            Log.wtf(TAG, e);
4254                        }
4255
4256                    }
4257                }
4258            }
4259        } finally {
4260            observer.stopWatching();
4261        }
4262    }
4263
4264    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4265        if (true || IS_USER_BUILD) {
4266            return;
4267        }
4268        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4269        if (tracesPath == null || tracesPath.length() == 0) {
4270            return;
4271        }
4272
4273        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4274        StrictMode.allowThreadDiskWrites();
4275        try {
4276            final File tracesFile = new File(tracesPath);
4277            final File tracesDir = tracesFile.getParentFile();
4278            final File tracesTmp = new File(tracesDir, "__tmp__");
4279            try {
4280                if (!tracesDir.exists()) {
4281                    tracesFile.mkdirs();
4282                    if (!SELinux.restorecon(tracesDir.getPath())) {
4283                        return;
4284                    }
4285                }
4286                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4287
4288                if (tracesFile.exists()) {
4289                    tracesTmp.delete();
4290                    tracesFile.renameTo(tracesTmp);
4291                }
4292                StringBuilder sb = new StringBuilder();
4293                Time tobj = new Time();
4294                tobj.set(System.currentTimeMillis());
4295                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4296                sb.append(": ");
4297                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4298                sb.append(" since ");
4299                sb.append(msg);
4300                FileOutputStream fos = new FileOutputStream(tracesFile);
4301                fos.write(sb.toString().getBytes());
4302                if (app == null) {
4303                    fos.write("\n*** No application process!".getBytes());
4304                }
4305                fos.close();
4306                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4307            } catch (IOException e) {
4308                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4309                return;
4310            }
4311
4312            if (app != null) {
4313                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4314                firstPids.add(app.pid);
4315                dumpStackTraces(tracesPath, firstPids, null, null, null);
4316            }
4317
4318            File lastTracesFile = null;
4319            File curTracesFile = null;
4320            for (int i=9; i>=0; i--) {
4321                String name = String.format(Locale.US, "slow%02d.txt", i);
4322                curTracesFile = new File(tracesDir, name);
4323                if (curTracesFile.exists()) {
4324                    if (lastTracesFile != null) {
4325                        curTracesFile.renameTo(lastTracesFile);
4326                    } else {
4327                        curTracesFile.delete();
4328                    }
4329                }
4330                lastTracesFile = curTracesFile;
4331            }
4332            tracesFile.renameTo(curTracesFile);
4333            if (tracesTmp.exists()) {
4334                tracesTmp.renameTo(tracesFile);
4335            }
4336        } finally {
4337            StrictMode.setThreadPolicy(oldPolicy);
4338        }
4339    }
4340
4341    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4342            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4343        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4344        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4345
4346        if (mController != null) {
4347            try {
4348                // 0 == continue, -1 = kill process immediately
4349                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4350                if (res < 0 && app.pid != MY_PID) {
4351                    Process.killProcess(app.pid);
4352                    Process.killProcessGroup(app.info.uid, app.pid);
4353                }
4354            } catch (RemoteException e) {
4355                mController = null;
4356                Watchdog.getInstance().setActivityController(null);
4357            }
4358        }
4359
4360        long anrTime = SystemClock.uptimeMillis();
4361        if (MONITOR_CPU_USAGE) {
4362            updateCpuStatsNow();
4363        }
4364
4365        synchronized (this) {
4366            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4367            if (mShuttingDown) {
4368                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4369                return;
4370            } else if (app.notResponding) {
4371                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4372                return;
4373            } else if (app.crashing) {
4374                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4375                return;
4376            }
4377
4378            // In case we come through here for the same app before completing
4379            // this one, mark as anring now so we will bail out.
4380            app.notResponding = true;
4381
4382            // Log the ANR to the event log.
4383            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4384                    app.processName, app.info.flags, annotation);
4385
4386            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4387            firstPids.add(app.pid);
4388
4389            int parentPid = app.pid;
4390            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4391            if (parentPid != app.pid) firstPids.add(parentPid);
4392
4393            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4394
4395            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4396                ProcessRecord r = mLruProcesses.get(i);
4397                if (r != null && r.thread != null) {
4398                    int pid = r.pid;
4399                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4400                        if (r.persistent) {
4401                            firstPids.add(pid);
4402                        } else {
4403                            lastPids.put(pid, Boolean.TRUE);
4404                        }
4405                    }
4406                }
4407            }
4408        }
4409
4410        // Log the ANR to the main log.
4411        StringBuilder info = new StringBuilder();
4412        info.setLength(0);
4413        info.append("ANR in ").append(app.processName);
4414        if (activity != null && activity.shortComponentName != null) {
4415            info.append(" (").append(activity.shortComponentName).append(")");
4416        }
4417        info.append("\n");
4418        info.append("PID: ").append(app.pid).append("\n");
4419        if (annotation != null) {
4420            info.append("Reason: ").append(annotation).append("\n");
4421        }
4422        if (parent != null && parent != activity) {
4423            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4424        }
4425
4426        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4427
4428        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4429                NATIVE_STACKS_OF_INTEREST);
4430
4431        String cpuInfo = null;
4432        if (MONITOR_CPU_USAGE) {
4433            updateCpuStatsNow();
4434            synchronized (mProcessCpuThread) {
4435                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4436            }
4437            info.append(processCpuTracker.printCurrentLoad());
4438            info.append(cpuInfo);
4439        }
4440
4441        info.append(processCpuTracker.printCurrentState(anrTime));
4442
4443        Slog.e(TAG, info.toString());
4444        if (tracesFile == null) {
4445            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4446            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4447        }
4448
4449        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4450                cpuInfo, tracesFile, null);
4451
4452        if (mController != null) {
4453            try {
4454                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4455                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4456                if (res != 0) {
4457                    if (res < 0 && app.pid != MY_PID) {
4458                        Process.killProcess(app.pid);
4459                        Process.killProcessGroup(app.info.uid, app.pid);
4460                    } else {
4461                        synchronized (this) {
4462                            mServices.scheduleServiceTimeoutLocked(app);
4463                        }
4464                    }
4465                    return;
4466                }
4467            } catch (RemoteException e) {
4468                mController = null;
4469                Watchdog.getInstance().setActivityController(null);
4470            }
4471        }
4472
4473        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4474        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4475                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4476
4477        synchronized (this) {
4478            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4479                killUnneededProcessLocked(app, "background ANR");
4480                return;
4481            }
4482
4483            // Set the app's notResponding state, and look up the errorReportReceiver
4484            makeAppNotRespondingLocked(app,
4485                    activity != null ? activity.shortComponentName : null,
4486                    annotation != null ? "ANR " + annotation : "ANR",
4487                    info.toString());
4488
4489            // Bring up the infamous App Not Responding dialog
4490            Message msg = Message.obtain();
4491            HashMap<String, Object> map = new HashMap<String, Object>();
4492            msg.what = SHOW_NOT_RESPONDING_MSG;
4493            msg.obj = map;
4494            msg.arg1 = aboveSystem ? 1 : 0;
4495            map.put("app", app);
4496            if (activity != null) {
4497                map.put("activity", activity);
4498            }
4499
4500            mHandler.sendMessage(msg);
4501        }
4502    }
4503
4504    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4505        if (!mLaunchWarningShown) {
4506            mLaunchWarningShown = true;
4507            mHandler.post(new Runnable() {
4508                @Override
4509                public void run() {
4510                    synchronized (ActivityManagerService.this) {
4511                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4512                        d.show();
4513                        mHandler.postDelayed(new Runnable() {
4514                            @Override
4515                            public void run() {
4516                                synchronized (ActivityManagerService.this) {
4517                                    d.dismiss();
4518                                    mLaunchWarningShown = false;
4519                                }
4520                            }
4521                        }, 4000);
4522                    }
4523                }
4524            });
4525        }
4526    }
4527
4528    @Override
4529    public boolean clearApplicationUserData(final String packageName,
4530            final IPackageDataObserver observer, int userId) {
4531        enforceNotIsolatedCaller("clearApplicationUserData");
4532        int uid = Binder.getCallingUid();
4533        int pid = Binder.getCallingPid();
4534        userId = handleIncomingUser(pid, uid,
4535                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4536        long callingId = Binder.clearCallingIdentity();
4537        try {
4538            IPackageManager pm = AppGlobals.getPackageManager();
4539            int pkgUid = -1;
4540            synchronized(this) {
4541                try {
4542                    pkgUid = pm.getPackageUid(packageName, userId);
4543                } catch (RemoteException e) {
4544                }
4545                if (pkgUid == -1) {
4546                    Slog.w(TAG, "Invalid packageName: " + packageName);
4547                    if (observer != null) {
4548                        try {
4549                            observer.onRemoveCompleted(packageName, false);
4550                        } catch (RemoteException e) {
4551                            Slog.i(TAG, "Observer no longer exists.");
4552                        }
4553                    }
4554                    return false;
4555                }
4556                if (uid == pkgUid || checkComponentPermission(
4557                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4558                        pid, uid, -1, true)
4559                        == PackageManager.PERMISSION_GRANTED) {
4560                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4561                } else {
4562                    throw new SecurityException("PID " + pid + " does not have permission "
4563                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4564                                    + " of package " + packageName);
4565                }
4566            }
4567
4568            try {
4569                // Clear application user data
4570                pm.clearApplicationUserData(packageName, observer, userId);
4571
4572                // Remove all permissions granted from/to this package
4573                removeUriPermissionsForPackageLocked(packageName, userId, true);
4574
4575                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4576                        Uri.fromParts("package", packageName, null));
4577                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4578                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4579                        null, null, 0, null, null, null, false, false, userId);
4580            } catch (RemoteException e) {
4581            }
4582        } finally {
4583            Binder.restoreCallingIdentity(callingId);
4584        }
4585        return true;
4586    }
4587
4588    @Override
4589    public void killBackgroundProcesses(final String packageName, int userId) {
4590        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4591                != PackageManager.PERMISSION_GRANTED &&
4592                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4593                        != PackageManager.PERMISSION_GRANTED) {
4594            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4595                    + Binder.getCallingPid()
4596                    + ", uid=" + Binder.getCallingUid()
4597                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4598            Slog.w(TAG, msg);
4599            throw new SecurityException(msg);
4600        }
4601
4602        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4603                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4604        long callingId = Binder.clearCallingIdentity();
4605        try {
4606            IPackageManager pm = AppGlobals.getPackageManager();
4607            synchronized(this) {
4608                int appId = -1;
4609                try {
4610                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4611                } catch (RemoteException e) {
4612                }
4613                if (appId == -1) {
4614                    Slog.w(TAG, "Invalid packageName: " + packageName);
4615                    return;
4616                }
4617                killPackageProcessesLocked(packageName, appId, userId,
4618                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4619            }
4620        } finally {
4621            Binder.restoreCallingIdentity(callingId);
4622        }
4623    }
4624
4625    @Override
4626    public void killAllBackgroundProcesses() {
4627        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4628                != PackageManager.PERMISSION_GRANTED) {
4629            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4630                    + Binder.getCallingPid()
4631                    + ", uid=" + Binder.getCallingUid()
4632                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4633            Slog.w(TAG, msg);
4634            throw new SecurityException(msg);
4635        }
4636
4637        long callingId = Binder.clearCallingIdentity();
4638        try {
4639            synchronized(this) {
4640                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4641                final int NP = mProcessNames.getMap().size();
4642                for (int ip=0; ip<NP; ip++) {
4643                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4644                    final int NA = apps.size();
4645                    for (int ia=0; ia<NA; ia++) {
4646                        ProcessRecord app = apps.valueAt(ia);
4647                        if (app.persistent) {
4648                            // we don't kill persistent processes
4649                            continue;
4650                        }
4651                        if (app.removed) {
4652                            procs.add(app);
4653                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4654                            app.removed = true;
4655                            procs.add(app);
4656                        }
4657                    }
4658                }
4659
4660                int N = procs.size();
4661                for (int i=0; i<N; i++) {
4662                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4663                }
4664                mAllowLowerMemLevel = true;
4665                updateOomAdjLocked();
4666                doLowMemReportIfNeededLocked(null);
4667            }
4668        } finally {
4669            Binder.restoreCallingIdentity(callingId);
4670        }
4671    }
4672
4673    @Override
4674    public void forceStopPackage(final String packageName, int userId) {
4675        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4676                != PackageManager.PERMISSION_GRANTED) {
4677            String msg = "Permission Denial: forceStopPackage() from pid="
4678                    + Binder.getCallingPid()
4679                    + ", uid=" + Binder.getCallingUid()
4680                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4681            Slog.w(TAG, msg);
4682            throw new SecurityException(msg);
4683        }
4684        final int callingPid = Binder.getCallingPid();
4685        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4686                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4687        long callingId = Binder.clearCallingIdentity();
4688        try {
4689            IPackageManager pm = AppGlobals.getPackageManager();
4690            synchronized(this) {
4691                int[] users = userId == UserHandle.USER_ALL
4692                        ? getUsersLocked() : new int[] { userId };
4693                for (int user : users) {
4694                    int pkgUid = -1;
4695                    try {
4696                        pkgUid = pm.getPackageUid(packageName, user);
4697                    } catch (RemoteException e) {
4698                    }
4699                    if (pkgUid == -1) {
4700                        Slog.w(TAG, "Invalid packageName: " + packageName);
4701                        continue;
4702                    }
4703                    try {
4704                        pm.setPackageStoppedState(packageName, true, user);
4705                    } catch (RemoteException e) {
4706                    } catch (IllegalArgumentException e) {
4707                        Slog.w(TAG, "Failed trying to unstop package "
4708                                + packageName + ": " + e);
4709                    }
4710                    if (isUserRunningLocked(user, false)) {
4711                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4712                    }
4713                }
4714            }
4715        } finally {
4716            Binder.restoreCallingIdentity(callingId);
4717        }
4718    }
4719
4720    @Override
4721    public void addPackageDependency(String packageName) {
4722        synchronized (this) {
4723            int callingPid = Binder.getCallingPid();
4724            if (callingPid == Process.myPid()) {
4725                //  Yeah, um, no.
4726                Slog.w(TAG, "Can't addPackageDependency on system process");
4727                return;
4728            }
4729            ProcessRecord proc;
4730            synchronized (mPidsSelfLocked) {
4731                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4732            }
4733            if (proc != null) {
4734                if (proc.pkgDeps == null) {
4735                    proc.pkgDeps = new ArraySet<String>(1);
4736                }
4737                proc.pkgDeps.add(packageName);
4738            }
4739        }
4740    }
4741
4742    /*
4743     * The pkg name and app id have to be specified.
4744     */
4745    @Override
4746    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4747        if (pkg == null) {
4748            return;
4749        }
4750        // Make sure the uid is valid.
4751        if (appid < 0) {
4752            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4753            return;
4754        }
4755        int callerUid = Binder.getCallingUid();
4756        // Only the system server can kill an application
4757        if (callerUid == Process.SYSTEM_UID) {
4758            // Post an aysnc message to kill the application
4759            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4760            msg.arg1 = appid;
4761            msg.arg2 = 0;
4762            Bundle bundle = new Bundle();
4763            bundle.putString("pkg", pkg);
4764            bundle.putString("reason", reason);
4765            msg.obj = bundle;
4766            mHandler.sendMessage(msg);
4767        } else {
4768            throw new SecurityException(callerUid + " cannot kill pkg: " +
4769                    pkg);
4770        }
4771    }
4772
4773    @Override
4774    public void closeSystemDialogs(String reason) {
4775        enforceNotIsolatedCaller("closeSystemDialogs");
4776
4777        final int pid = Binder.getCallingPid();
4778        final int uid = Binder.getCallingUid();
4779        final long origId = Binder.clearCallingIdentity();
4780        try {
4781            synchronized (this) {
4782                // Only allow this from foreground processes, so that background
4783                // applications can't abuse it to prevent system UI from being shown.
4784                if (uid >= Process.FIRST_APPLICATION_UID) {
4785                    ProcessRecord proc;
4786                    synchronized (mPidsSelfLocked) {
4787                        proc = mPidsSelfLocked.get(pid);
4788                    }
4789                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4790                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4791                                + " from background process " + proc);
4792                        return;
4793                    }
4794                }
4795                closeSystemDialogsLocked(reason);
4796            }
4797        } finally {
4798            Binder.restoreCallingIdentity(origId);
4799        }
4800    }
4801
4802    void closeSystemDialogsLocked(String reason) {
4803        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4804        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4805                | Intent.FLAG_RECEIVER_FOREGROUND);
4806        if (reason != null) {
4807            intent.putExtra("reason", reason);
4808        }
4809        mWindowManager.closeSystemDialogs(reason);
4810
4811        mStackSupervisor.closeSystemDialogsLocked();
4812
4813        broadcastIntentLocked(null, null, intent, null,
4814                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4815                Process.SYSTEM_UID, UserHandle.USER_ALL);
4816    }
4817
4818    @Override
4819    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4820        enforceNotIsolatedCaller("getProcessMemoryInfo");
4821        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4822        for (int i=pids.length-1; i>=0; i--) {
4823            ProcessRecord proc;
4824            int oomAdj;
4825            synchronized (this) {
4826                synchronized (mPidsSelfLocked) {
4827                    proc = mPidsSelfLocked.get(pids[i]);
4828                    oomAdj = proc != null ? proc.setAdj : 0;
4829                }
4830            }
4831            infos[i] = new Debug.MemoryInfo();
4832            Debug.getMemoryInfo(pids[i], infos[i]);
4833            if (proc != null) {
4834                synchronized (this) {
4835                    if (proc.thread != null && proc.setAdj == oomAdj) {
4836                        // Record this for posterity if the process has been stable.
4837                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4838                                infos[i].getTotalUss(), false, proc.pkgList);
4839                    }
4840                }
4841            }
4842        }
4843        return infos;
4844    }
4845
4846    @Override
4847    public long[] getProcessPss(int[] pids) {
4848        enforceNotIsolatedCaller("getProcessPss");
4849        long[] pss = new long[pids.length];
4850        for (int i=pids.length-1; i>=0; i--) {
4851            ProcessRecord proc;
4852            int oomAdj;
4853            synchronized (this) {
4854                synchronized (mPidsSelfLocked) {
4855                    proc = mPidsSelfLocked.get(pids[i]);
4856                    oomAdj = proc != null ? proc.setAdj : 0;
4857                }
4858            }
4859            long[] tmpUss = new long[1];
4860            pss[i] = Debug.getPss(pids[i], tmpUss);
4861            if (proc != null) {
4862                synchronized (this) {
4863                    if (proc.thread != null && proc.setAdj == oomAdj) {
4864                        // Record this for posterity if the process has been stable.
4865                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4866                    }
4867                }
4868            }
4869        }
4870        return pss;
4871    }
4872
4873    @Override
4874    public void killApplicationProcess(String processName, int uid) {
4875        if (processName == null) {
4876            return;
4877        }
4878
4879        int callerUid = Binder.getCallingUid();
4880        // Only the system server can kill an application
4881        if (callerUid == Process.SYSTEM_UID) {
4882            synchronized (this) {
4883                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4884                if (app != null && app.thread != null) {
4885                    try {
4886                        app.thread.scheduleSuicide();
4887                    } catch (RemoteException e) {
4888                        // If the other end already died, then our work here is done.
4889                    }
4890                } else {
4891                    Slog.w(TAG, "Process/uid not found attempting kill of "
4892                            + processName + " / " + uid);
4893                }
4894            }
4895        } else {
4896            throw new SecurityException(callerUid + " cannot kill app process: " +
4897                    processName);
4898        }
4899    }
4900
4901    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4902        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4903                false, true, false, false, UserHandle.getUserId(uid), reason);
4904        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4905                Uri.fromParts("package", packageName, null));
4906        if (!mProcessesReady) {
4907            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4908                    | Intent.FLAG_RECEIVER_FOREGROUND);
4909        }
4910        intent.putExtra(Intent.EXTRA_UID, uid);
4911        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4912        broadcastIntentLocked(null, null, intent,
4913                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4914                false, false,
4915                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4916    }
4917
4918    private void forceStopUserLocked(int userId, String reason) {
4919        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4920        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4921        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4922                | Intent.FLAG_RECEIVER_FOREGROUND);
4923        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4924        broadcastIntentLocked(null, null, intent,
4925                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4926                false, false,
4927                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4928    }
4929
4930    private final boolean killPackageProcessesLocked(String packageName, int appId,
4931            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4932            boolean doit, boolean evenPersistent, String reason) {
4933        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4934
4935        // Remove all processes this package may have touched: all with the
4936        // same UID (except for the system or root user), and all whose name
4937        // matches the package name.
4938        final int NP = mProcessNames.getMap().size();
4939        for (int ip=0; ip<NP; ip++) {
4940            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4941            final int NA = apps.size();
4942            for (int ia=0; ia<NA; ia++) {
4943                ProcessRecord app = apps.valueAt(ia);
4944                if (app.persistent && !evenPersistent) {
4945                    // we don't kill persistent processes
4946                    continue;
4947                }
4948                if (app.removed) {
4949                    if (doit) {
4950                        procs.add(app);
4951                    }
4952                    continue;
4953                }
4954
4955                // Skip process if it doesn't meet our oom adj requirement.
4956                if (app.setAdj < minOomAdj) {
4957                    continue;
4958                }
4959
4960                // If no package is specified, we call all processes under the
4961                // give user id.
4962                if (packageName == null) {
4963                    if (app.userId != userId) {
4964                        continue;
4965                    }
4966                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4967                        continue;
4968                    }
4969                // Package has been specified, we want to hit all processes
4970                // that match it.  We need to qualify this by the processes
4971                // that are running under the specified app and user ID.
4972                } else {
4973                    final boolean isDep = app.pkgDeps != null
4974                            && app.pkgDeps.contains(packageName);
4975                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
4976                        continue;
4977                    }
4978                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4979                        continue;
4980                    }
4981                    if (!app.pkgList.containsKey(packageName) && !isDep) {
4982                        continue;
4983                    }
4984                }
4985
4986                // Process has passed all conditions, kill it!
4987                if (!doit) {
4988                    return true;
4989                }
4990                app.removed = true;
4991                procs.add(app);
4992            }
4993        }
4994
4995        int N = procs.size();
4996        for (int i=0; i<N; i++) {
4997            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4998        }
4999        updateOomAdjLocked();
5000        return N > 0;
5001    }
5002
5003    private final boolean forceStopPackageLocked(String name, int appId,
5004            boolean callerWillRestart, boolean purgeCache, boolean doit,
5005            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5006        int i;
5007        int N;
5008
5009        if (userId == UserHandle.USER_ALL && name == null) {
5010            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5011        }
5012
5013        if (appId < 0 && name != null) {
5014            try {
5015                appId = UserHandle.getAppId(
5016                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5017            } catch (RemoteException e) {
5018            }
5019        }
5020
5021        if (doit) {
5022            if (name != null) {
5023                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5024                        + " user=" + userId + ": " + reason);
5025            } else {
5026                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5027            }
5028
5029            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5030            for (int ip=pmap.size()-1; ip>=0; ip--) {
5031                SparseArray<Long> ba = pmap.valueAt(ip);
5032                for (i=ba.size()-1; i>=0; i--) {
5033                    boolean remove = false;
5034                    final int entUid = ba.keyAt(i);
5035                    if (name != null) {
5036                        if (userId == UserHandle.USER_ALL) {
5037                            if (UserHandle.getAppId(entUid) == appId) {
5038                                remove = true;
5039                            }
5040                        } else {
5041                            if (entUid == UserHandle.getUid(userId, appId)) {
5042                                remove = true;
5043                            }
5044                        }
5045                    } else if (UserHandle.getUserId(entUid) == userId) {
5046                        remove = true;
5047                    }
5048                    if (remove) {
5049                        ba.removeAt(i);
5050                    }
5051                }
5052                if (ba.size() == 0) {
5053                    pmap.removeAt(ip);
5054                }
5055            }
5056        }
5057
5058        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5059                -100, callerWillRestart, true, doit, evenPersistent,
5060                name == null ? ("stop user " + userId) : ("stop " + name));
5061
5062        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5063            if (!doit) {
5064                return true;
5065            }
5066            didSomething = true;
5067        }
5068
5069        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5070            if (!doit) {
5071                return true;
5072            }
5073            didSomething = true;
5074        }
5075
5076        if (name == null) {
5077            // Remove all sticky broadcasts from this user.
5078            mStickyBroadcasts.remove(userId);
5079        }
5080
5081        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5082        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5083                userId, providers)) {
5084            if (!doit) {
5085                return true;
5086            }
5087            didSomething = true;
5088        }
5089        N = providers.size();
5090        for (i=0; i<N; i++) {
5091            removeDyingProviderLocked(null, providers.get(i), true);
5092        }
5093
5094        // Remove transient permissions granted from/to this package/user
5095        removeUriPermissionsForPackageLocked(name, userId, false);
5096
5097        if (name == null || uninstalling) {
5098            // Remove pending intents.  For now we only do this when force
5099            // stopping users, because we have some problems when doing this
5100            // for packages -- app widgets are not currently cleaned up for
5101            // such packages, so they can be left with bad pending intents.
5102            if (mIntentSenderRecords.size() > 0) {
5103                Iterator<WeakReference<PendingIntentRecord>> it
5104                        = mIntentSenderRecords.values().iterator();
5105                while (it.hasNext()) {
5106                    WeakReference<PendingIntentRecord> wpir = it.next();
5107                    if (wpir == null) {
5108                        it.remove();
5109                        continue;
5110                    }
5111                    PendingIntentRecord pir = wpir.get();
5112                    if (pir == null) {
5113                        it.remove();
5114                        continue;
5115                    }
5116                    if (name == null) {
5117                        // Stopping user, remove all objects for the user.
5118                        if (pir.key.userId != userId) {
5119                            // Not the same user, skip it.
5120                            continue;
5121                        }
5122                    } else {
5123                        if (UserHandle.getAppId(pir.uid) != appId) {
5124                            // Different app id, skip it.
5125                            continue;
5126                        }
5127                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5128                            // Different user, skip it.
5129                            continue;
5130                        }
5131                        if (!pir.key.packageName.equals(name)) {
5132                            // Different package, skip it.
5133                            continue;
5134                        }
5135                    }
5136                    if (!doit) {
5137                        return true;
5138                    }
5139                    didSomething = true;
5140                    it.remove();
5141                    pir.canceled = true;
5142                    if (pir.key.activity != null) {
5143                        pir.key.activity.pendingResults.remove(pir.ref);
5144                    }
5145                }
5146            }
5147        }
5148
5149        if (doit) {
5150            if (purgeCache && name != null) {
5151                AttributeCache ac = AttributeCache.instance();
5152                if (ac != null) {
5153                    ac.removePackage(name);
5154                }
5155            }
5156            if (mBooted) {
5157                mStackSupervisor.resumeTopActivitiesLocked();
5158                mStackSupervisor.scheduleIdleLocked();
5159            }
5160        }
5161
5162        return didSomething;
5163    }
5164
5165    private final boolean removeProcessLocked(ProcessRecord app,
5166            boolean callerWillRestart, boolean allowRestart, String reason) {
5167        final String name = app.processName;
5168        final int uid = app.uid;
5169        if (DEBUG_PROCESSES) Slog.d(
5170            TAG, "Force removing proc " + app.toShortString() + " (" + name
5171            + "/" + uid + ")");
5172
5173        mProcessNames.remove(name, uid);
5174        mIsolatedProcesses.remove(app.uid);
5175        if (mHeavyWeightProcess == app) {
5176            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5177                    mHeavyWeightProcess.userId, 0));
5178            mHeavyWeightProcess = null;
5179        }
5180        boolean needRestart = false;
5181        if (app.pid > 0 && app.pid != MY_PID) {
5182            int pid = app.pid;
5183            synchronized (mPidsSelfLocked) {
5184                mPidsSelfLocked.remove(pid);
5185                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5186            }
5187            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5188            if (app.isolated) {
5189                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5190            }
5191            killUnneededProcessLocked(app, reason);
5192            Process.killProcessGroup(app.info.uid, app.pid);
5193            handleAppDiedLocked(app, true, allowRestart);
5194            removeLruProcessLocked(app);
5195
5196            if (app.persistent && !app.isolated) {
5197                if (!callerWillRestart) {
5198                    addAppLocked(app.info, false, null /* ABI override */);
5199                } else {
5200                    needRestart = true;
5201                }
5202            }
5203        } else {
5204            mRemovedProcesses.add(app);
5205        }
5206
5207        return needRestart;
5208    }
5209
5210    private final void processStartTimedOutLocked(ProcessRecord app) {
5211        final int pid = app.pid;
5212        boolean gone = false;
5213        synchronized (mPidsSelfLocked) {
5214            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5215            if (knownApp != null && knownApp.thread == null) {
5216                mPidsSelfLocked.remove(pid);
5217                gone = true;
5218            }
5219        }
5220
5221        if (gone) {
5222            Slog.w(TAG, "Process " + app + " failed to attach");
5223            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5224                    pid, app.uid, app.processName);
5225            mProcessNames.remove(app.processName, app.uid);
5226            mIsolatedProcesses.remove(app.uid);
5227            if (mHeavyWeightProcess == app) {
5228                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5229                        mHeavyWeightProcess.userId, 0));
5230                mHeavyWeightProcess = null;
5231            }
5232            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5233            if (app.isolated) {
5234                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5235            }
5236            // Take care of any launching providers waiting for this process.
5237            checkAppInLaunchingProvidersLocked(app, true);
5238            // Take care of any services that are waiting for the process.
5239            mServices.processStartTimedOutLocked(app);
5240            killUnneededProcessLocked(app, "start timeout");
5241            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5242                Slog.w(TAG, "Unattached app died before backup, skipping");
5243                try {
5244                    IBackupManager bm = IBackupManager.Stub.asInterface(
5245                            ServiceManager.getService(Context.BACKUP_SERVICE));
5246                    bm.agentDisconnected(app.info.packageName);
5247                } catch (RemoteException e) {
5248                    // Can't happen; the backup manager is local
5249                }
5250            }
5251            if (isPendingBroadcastProcessLocked(pid)) {
5252                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5253                skipPendingBroadcastLocked(pid);
5254            }
5255        } else {
5256            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5257        }
5258    }
5259
5260    private final boolean attachApplicationLocked(IApplicationThread thread,
5261            int pid) {
5262
5263        // Find the application record that is being attached...  either via
5264        // the pid if we are running in multiple processes, or just pull the
5265        // next app record if we are emulating process with anonymous threads.
5266        ProcessRecord app;
5267        if (pid != MY_PID && pid >= 0) {
5268            synchronized (mPidsSelfLocked) {
5269                app = mPidsSelfLocked.get(pid);
5270            }
5271        } else {
5272            app = null;
5273        }
5274
5275        if (app == null) {
5276            Slog.w(TAG, "No pending application record for pid " + pid
5277                    + " (IApplicationThread " + thread + "); dropping process");
5278            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5279            if (pid > 0 && pid != MY_PID) {
5280                Process.killProcessQuiet(pid);
5281                //TODO: Process.killProcessGroup(app.info.uid, pid);
5282            } else {
5283                try {
5284                    thread.scheduleExit();
5285                } catch (Exception e) {
5286                    // Ignore exceptions.
5287                }
5288            }
5289            return false;
5290        }
5291
5292        // If this application record is still attached to a previous
5293        // process, clean it up now.
5294        if (app.thread != null) {
5295            handleAppDiedLocked(app, true, true);
5296        }
5297
5298        // Tell the process all about itself.
5299
5300        if (localLOGV) Slog.v(
5301                TAG, "Binding process pid " + pid + " to record " + app);
5302
5303        final String processName = app.processName;
5304        try {
5305            AppDeathRecipient adr = new AppDeathRecipient(
5306                    app, pid, thread);
5307            thread.asBinder().linkToDeath(adr, 0);
5308            app.deathRecipient = adr;
5309        } catch (RemoteException e) {
5310            app.resetPackageList(mProcessStats);
5311            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5312            return false;
5313        }
5314
5315        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5316
5317        app.makeActive(thread, mProcessStats);
5318        app.curAdj = app.setAdj = -100;
5319        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5320        app.forcingToForeground = null;
5321        updateProcessForegroundLocked(app, false, false);
5322        app.hasShownUi = false;
5323        app.debugging = false;
5324        app.cached = false;
5325
5326        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5327
5328        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5329        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5330
5331        if (!normalMode) {
5332            Slog.i(TAG, "Launching preboot mode app: " + app);
5333        }
5334
5335        if (localLOGV) Slog.v(
5336            TAG, "New app record " + app
5337            + " thread=" + thread.asBinder() + " pid=" + pid);
5338        try {
5339            int testMode = IApplicationThread.DEBUG_OFF;
5340            if (mDebugApp != null && mDebugApp.equals(processName)) {
5341                testMode = mWaitForDebugger
5342                    ? IApplicationThread.DEBUG_WAIT
5343                    : IApplicationThread.DEBUG_ON;
5344                app.debugging = true;
5345                if (mDebugTransient) {
5346                    mDebugApp = mOrigDebugApp;
5347                    mWaitForDebugger = mOrigWaitForDebugger;
5348                }
5349            }
5350            String profileFile = app.instrumentationProfileFile;
5351            ParcelFileDescriptor profileFd = null;
5352            boolean profileAutoStop = false;
5353            if (mProfileApp != null && mProfileApp.equals(processName)) {
5354                mProfileProc = app;
5355                profileFile = mProfileFile;
5356                profileFd = mProfileFd;
5357                profileAutoStop = mAutoStopProfiler;
5358            }
5359            boolean enableOpenGlTrace = false;
5360            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5361                enableOpenGlTrace = true;
5362                mOpenGlTraceApp = null;
5363            }
5364
5365            // If the app is being launched for restore or full backup, set it up specially
5366            boolean isRestrictedBackupMode = false;
5367            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5368                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5369                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5370                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5371            }
5372
5373            ensurePackageDexOpt(app.instrumentationInfo != null
5374                    ? app.instrumentationInfo.packageName
5375                    : app.info.packageName);
5376            if (app.instrumentationClass != null) {
5377                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5378            }
5379            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5380                    + processName + " with config " + mConfiguration);
5381            ApplicationInfo appInfo = app.instrumentationInfo != null
5382                    ? app.instrumentationInfo : app.info;
5383            app.compat = compatibilityInfoForPackageLocked(appInfo);
5384            if (profileFd != null) {
5385                profileFd = profileFd.dup();
5386            }
5387            thread.bindApplication(processName, appInfo, providers,
5388                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5389                    app.instrumentationArguments, app.instrumentationWatcher,
5390                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5391                    isRestrictedBackupMode || !normalMode, app.persistent,
5392                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5393                    mCoreSettingsObserver.getCoreSettingsLocked());
5394            updateLruProcessLocked(app, false, null);
5395            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5396        } catch (Exception e) {
5397            // todo: Yikes!  What should we do?  For now we will try to
5398            // start another process, but that could easily get us in
5399            // an infinite loop of restarting processes...
5400            Slog.w(TAG, "Exception thrown during bind!", e);
5401
5402            app.resetPackageList(mProcessStats);
5403            app.unlinkDeathRecipient();
5404            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5405            return false;
5406        }
5407
5408        // Remove this record from the list of starting applications.
5409        mPersistentStartingProcesses.remove(app);
5410        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5411                "Attach application locked removing on hold: " + app);
5412        mProcessesOnHold.remove(app);
5413
5414        boolean badApp = false;
5415        boolean didSomething = false;
5416
5417        // See if the top visible activity is waiting to run in this process...
5418        if (normalMode) {
5419            try {
5420                if (mStackSupervisor.attachApplicationLocked(app)) {
5421                    didSomething = true;
5422                }
5423            } catch (Exception e) {
5424                badApp = true;
5425            }
5426        }
5427
5428        // Find any services that should be running in this process...
5429        if (!badApp) {
5430            try {
5431                didSomething |= mServices.attachApplicationLocked(app, processName);
5432            } catch (Exception e) {
5433                badApp = true;
5434            }
5435        }
5436
5437        // Check if a next-broadcast receiver is in this process...
5438        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5439            try {
5440                didSomething |= sendPendingBroadcastsLocked(app);
5441            } catch (Exception e) {
5442                // If the app died trying to launch the receiver we declare it 'bad'
5443                badApp = true;
5444            }
5445        }
5446
5447        // Check whether the next backup agent is in this process...
5448        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5449            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5450            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5451            try {
5452                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5453                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5454                        mBackupTarget.backupMode);
5455            } catch (Exception e) {
5456                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5457                e.printStackTrace();
5458            }
5459        }
5460
5461        if (badApp) {
5462            // todo: Also need to kill application to deal with all
5463            // kinds of exceptions.
5464            handleAppDiedLocked(app, false, true);
5465            return false;
5466        }
5467
5468        if (!didSomething) {
5469            updateOomAdjLocked();
5470        }
5471
5472        return true;
5473    }
5474
5475    @Override
5476    public final void attachApplication(IApplicationThread thread) {
5477        synchronized (this) {
5478            int callingPid = Binder.getCallingPid();
5479            final long origId = Binder.clearCallingIdentity();
5480            attachApplicationLocked(thread, callingPid);
5481            Binder.restoreCallingIdentity(origId);
5482        }
5483    }
5484
5485    @Override
5486    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5487        final long origId = Binder.clearCallingIdentity();
5488        synchronized (this) {
5489            ActivityStack stack = ActivityRecord.getStackLocked(token);
5490            if (stack != null) {
5491                ActivityRecord r =
5492                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5493                if (stopProfiling) {
5494                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5495                        try {
5496                            mProfileFd.close();
5497                        } catch (IOException e) {
5498                        }
5499                        clearProfilerLocked();
5500                    }
5501                }
5502            }
5503        }
5504        Binder.restoreCallingIdentity(origId);
5505    }
5506
5507    void enableScreenAfterBoot() {
5508        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5509                SystemClock.uptimeMillis());
5510        mWindowManager.enableScreenAfterBoot();
5511
5512        synchronized (this) {
5513            updateEventDispatchingLocked();
5514        }
5515    }
5516
5517    @Override
5518    public void showBootMessage(final CharSequence msg, final boolean always) {
5519        enforceNotIsolatedCaller("showBootMessage");
5520        mWindowManager.showBootMessage(msg, always);
5521    }
5522
5523    @Override
5524    public void dismissKeyguardOnNextActivity() {
5525        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5526        final long token = Binder.clearCallingIdentity();
5527        try {
5528            synchronized (this) {
5529                if (DEBUG_LOCKSCREEN) logLockScreen("");
5530                if (mLockScreenShown) {
5531                    mLockScreenShown = false;
5532                    comeOutOfSleepIfNeededLocked();
5533                }
5534                mStackSupervisor.setDismissKeyguard(true);
5535            }
5536        } finally {
5537            Binder.restoreCallingIdentity(token);
5538        }
5539    }
5540
5541    final void finishBooting() {
5542        // Register receivers to handle package update events
5543        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5544
5545        synchronized (this) {
5546            // Ensure that any processes we had put on hold are now started
5547            // up.
5548            final int NP = mProcessesOnHold.size();
5549            if (NP > 0) {
5550                ArrayList<ProcessRecord> procs =
5551                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5552                for (int ip=0; ip<NP; ip++) {
5553                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5554                            + procs.get(ip));
5555                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5556                }
5557            }
5558
5559            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5560                // Start looking for apps that are abusing wake locks.
5561                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5562                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5563                // Tell anyone interested that we are done booting!
5564                SystemProperties.set("sys.boot_completed", "1");
5565                SystemProperties.set("dev.bootcomplete", "1");
5566                for (int i=0; i<mStartedUsers.size(); i++) {
5567                    UserStartedState uss = mStartedUsers.valueAt(i);
5568                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5569                        uss.mState = UserStartedState.STATE_RUNNING;
5570                        final int userId = mStartedUsers.keyAt(i);
5571                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5572                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5573                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5574                        broadcastIntentLocked(null, null, intent, null,
5575                                new IIntentReceiver.Stub() {
5576                                    @Override
5577                                    public void performReceive(Intent intent, int resultCode,
5578                                            String data, Bundle extras, boolean ordered,
5579                                            boolean sticky, int sendingUser) {
5580                                        synchronized (ActivityManagerService.this) {
5581                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5582                                                    true, false);
5583                                        }
5584                                    }
5585                                },
5586                                0, null, null,
5587                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5588                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5589                                userId);
5590                    }
5591                }
5592                scheduleStartProfilesLocked();
5593            }
5594        }
5595    }
5596
5597    final void ensureBootCompleted() {
5598        boolean booting;
5599        boolean enableScreen;
5600        synchronized (this) {
5601            booting = mBooting;
5602            mBooting = false;
5603            enableScreen = !mBooted;
5604            mBooted = true;
5605        }
5606
5607        if (booting) {
5608            finishBooting();
5609        }
5610
5611        if (enableScreen) {
5612            enableScreenAfterBoot();
5613        }
5614    }
5615
5616    @Override
5617    public final void activityResumed(IBinder token) {
5618        final long origId = Binder.clearCallingIdentity();
5619        synchronized(this) {
5620            ActivityStack stack = ActivityRecord.getStackLocked(token);
5621            if (stack != null) {
5622                ActivityRecord.activityResumedLocked(token);
5623            }
5624        }
5625        Binder.restoreCallingIdentity(origId);
5626    }
5627
5628    @Override
5629    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5630        final long origId = Binder.clearCallingIdentity();
5631        synchronized(this) {
5632            ActivityStack stack = ActivityRecord.getStackLocked(token);
5633            if (stack != null) {
5634                stack.activityPausedLocked(token, false, persistentState);
5635            }
5636        }
5637        Binder.restoreCallingIdentity(origId);
5638    }
5639
5640    @Override
5641    public final void activityStopped(IBinder token, Bundle icicle,
5642            PersistableBundle persistentState, CharSequence description) {
5643        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5644
5645        // Refuse possible leaked file descriptors
5646        if (icicle != null && icicle.hasFileDescriptors()) {
5647            throw new IllegalArgumentException("File descriptors passed in Bundle");
5648        }
5649
5650        final long origId = Binder.clearCallingIdentity();
5651
5652        synchronized (this) {
5653            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5654            if (r != null) {
5655                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5656            }
5657        }
5658
5659        trimApplications();
5660
5661        Binder.restoreCallingIdentity(origId);
5662    }
5663
5664    @Override
5665    public final void activityDestroyed(IBinder token) {
5666        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5667        synchronized (this) {
5668            ActivityStack stack = ActivityRecord.getStackLocked(token);
5669            if (stack != null) {
5670                stack.activityDestroyedLocked(token);
5671            }
5672        }
5673    }
5674
5675    @Override
5676    public final void mediaResourcesReleased(IBinder token) {
5677        final long origId = Binder.clearCallingIdentity();
5678        try {
5679            synchronized (this) {
5680                ActivityStack stack = ActivityRecord.getStackLocked(token);
5681                if (stack != null) {
5682                    stack.mediaResourcesReleased(token);
5683                }
5684            }
5685        } finally {
5686            Binder.restoreCallingIdentity(origId);
5687        }
5688    }
5689
5690    @Override
5691    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5692        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5693    }
5694
5695    @Override
5696    public String getCallingPackage(IBinder token) {
5697        synchronized (this) {
5698            ActivityRecord r = getCallingRecordLocked(token);
5699            return r != null ? r.info.packageName : null;
5700        }
5701    }
5702
5703    @Override
5704    public ComponentName getCallingActivity(IBinder token) {
5705        synchronized (this) {
5706            ActivityRecord r = getCallingRecordLocked(token);
5707            return r != null ? r.intent.getComponent() : null;
5708        }
5709    }
5710
5711    private ActivityRecord getCallingRecordLocked(IBinder token) {
5712        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5713        if (r == null) {
5714            return null;
5715        }
5716        return r.resultTo;
5717    }
5718
5719    @Override
5720    public ComponentName getActivityClassForToken(IBinder token) {
5721        synchronized(this) {
5722            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5723            if (r == null) {
5724                return null;
5725            }
5726            return r.intent.getComponent();
5727        }
5728    }
5729
5730    @Override
5731    public String getPackageForToken(IBinder token) {
5732        synchronized(this) {
5733            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5734            if (r == null) {
5735                return null;
5736            }
5737            return r.packageName;
5738        }
5739    }
5740
5741    @Override
5742    public IIntentSender getIntentSender(int type,
5743            String packageName, IBinder token, String resultWho,
5744            int requestCode, Intent[] intents, String[] resolvedTypes,
5745            int flags, Bundle options, int userId) {
5746        enforceNotIsolatedCaller("getIntentSender");
5747        // Refuse possible leaked file descriptors
5748        if (intents != null) {
5749            if (intents.length < 1) {
5750                throw new IllegalArgumentException("Intents array length must be >= 1");
5751            }
5752            for (int i=0; i<intents.length; i++) {
5753                Intent intent = intents[i];
5754                if (intent != null) {
5755                    if (intent.hasFileDescriptors()) {
5756                        throw new IllegalArgumentException("File descriptors passed in Intent");
5757                    }
5758                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5759                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5760                        throw new IllegalArgumentException(
5761                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5762                    }
5763                    intents[i] = new Intent(intent);
5764                }
5765            }
5766            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5767                throw new IllegalArgumentException(
5768                        "Intent array length does not match resolvedTypes length");
5769            }
5770        }
5771        if (options != null) {
5772            if (options.hasFileDescriptors()) {
5773                throw new IllegalArgumentException("File descriptors passed in options");
5774            }
5775        }
5776
5777        synchronized(this) {
5778            int callingUid = Binder.getCallingUid();
5779            int origUserId = userId;
5780            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5781                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5782                    ALLOW_NON_FULL, "getIntentSender", null);
5783            if (origUserId == UserHandle.USER_CURRENT) {
5784                // We don't want to evaluate this until the pending intent is
5785                // actually executed.  However, we do want to always do the
5786                // security checking for it above.
5787                userId = UserHandle.USER_CURRENT;
5788            }
5789            try {
5790                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5791                    int uid = AppGlobals.getPackageManager()
5792                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5793                    if (!UserHandle.isSameApp(callingUid, uid)) {
5794                        String msg = "Permission Denial: getIntentSender() from pid="
5795                            + Binder.getCallingPid()
5796                            + ", uid=" + Binder.getCallingUid()
5797                            + ", (need uid=" + uid + ")"
5798                            + " is not allowed to send as package " + packageName;
5799                        Slog.w(TAG, msg);
5800                        throw new SecurityException(msg);
5801                    }
5802                }
5803
5804                return getIntentSenderLocked(type, packageName, callingUid, userId,
5805                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5806
5807            } catch (RemoteException e) {
5808                throw new SecurityException(e);
5809            }
5810        }
5811    }
5812
5813    IIntentSender getIntentSenderLocked(int type, String packageName,
5814            int callingUid, int userId, IBinder token, String resultWho,
5815            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5816            Bundle options) {
5817        if (DEBUG_MU)
5818            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5819        ActivityRecord activity = null;
5820        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5821            activity = ActivityRecord.isInStackLocked(token);
5822            if (activity == null) {
5823                return null;
5824            }
5825            if (activity.finishing) {
5826                return null;
5827            }
5828        }
5829
5830        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5831        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5832        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5833        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5834                |PendingIntent.FLAG_UPDATE_CURRENT);
5835
5836        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5837                type, packageName, activity, resultWho,
5838                requestCode, intents, resolvedTypes, flags, options, userId);
5839        WeakReference<PendingIntentRecord> ref;
5840        ref = mIntentSenderRecords.get(key);
5841        PendingIntentRecord rec = ref != null ? ref.get() : null;
5842        if (rec != null) {
5843            if (!cancelCurrent) {
5844                if (updateCurrent) {
5845                    if (rec.key.requestIntent != null) {
5846                        rec.key.requestIntent.replaceExtras(intents != null ?
5847                                intents[intents.length - 1] : null);
5848                    }
5849                    if (intents != null) {
5850                        intents[intents.length-1] = rec.key.requestIntent;
5851                        rec.key.allIntents = intents;
5852                        rec.key.allResolvedTypes = resolvedTypes;
5853                    } else {
5854                        rec.key.allIntents = null;
5855                        rec.key.allResolvedTypes = null;
5856                    }
5857                }
5858                return rec;
5859            }
5860            rec.canceled = true;
5861            mIntentSenderRecords.remove(key);
5862        }
5863        if (noCreate) {
5864            return rec;
5865        }
5866        rec = new PendingIntentRecord(this, key, callingUid);
5867        mIntentSenderRecords.put(key, rec.ref);
5868        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5869            if (activity.pendingResults == null) {
5870                activity.pendingResults
5871                        = new HashSet<WeakReference<PendingIntentRecord>>();
5872            }
5873            activity.pendingResults.add(rec.ref);
5874        }
5875        return rec;
5876    }
5877
5878    @Override
5879    public void cancelIntentSender(IIntentSender sender) {
5880        if (!(sender instanceof PendingIntentRecord)) {
5881            return;
5882        }
5883        synchronized(this) {
5884            PendingIntentRecord rec = (PendingIntentRecord)sender;
5885            try {
5886                int uid = AppGlobals.getPackageManager()
5887                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5888                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5889                    String msg = "Permission Denial: cancelIntentSender() from pid="
5890                        + Binder.getCallingPid()
5891                        + ", uid=" + Binder.getCallingUid()
5892                        + " is not allowed to cancel packges "
5893                        + rec.key.packageName;
5894                    Slog.w(TAG, msg);
5895                    throw new SecurityException(msg);
5896                }
5897            } catch (RemoteException e) {
5898                throw new SecurityException(e);
5899            }
5900            cancelIntentSenderLocked(rec, true);
5901        }
5902    }
5903
5904    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5905        rec.canceled = true;
5906        mIntentSenderRecords.remove(rec.key);
5907        if (cleanActivity && rec.key.activity != null) {
5908            rec.key.activity.pendingResults.remove(rec.ref);
5909        }
5910    }
5911
5912    @Override
5913    public String getPackageForIntentSender(IIntentSender pendingResult) {
5914        if (!(pendingResult instanceof PendingIntentRecord)) {
5915            return null;
5916        }
5917        try {
5918            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5919            return res.key.packageName;
5920        } catch (ClassCastException e) {
5921        }
5922        return null;
5923    }
5924
5925    @Override
5926    public int getUidForIntentSender(IIntentSender sender) {
5927        if (sender instanceof PendingIntentRecord) {
5928            try {
5929                PendingIntentRecord res = (PendingIntentRecord)sender;
5930                return res.uid;
5931            } catch (ClassCastException e) {
5932            }
5933        }
5934        return -1;
5935    }
5936
5937    @Override
5938    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5939        if (!(pendingResult instanceof PendingIntentRecord)) {
5940            return false;
5941        }
5942        try {
5943            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5944            if (res.key.allIntents == null) {
5945                return false;
5946            }
5947            for (int i=0; i<res.key.allIntents.length; i++) {
5948                Intent intent = res.key.allIntents[i];
5949                if (intent.getPackage() != null && intent.getComponent() != null) {
5950                    return false;
5951                }
5952            }
5953            return true;
5954        } catch (ClassCastException e) {
5955        }
5956        return false;
5957    }
5958
5959    @Override
5960    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5961        if (!(pendingResult instanceof PendingIntentRecord)) {
5962            return false;
5963        }
5964        try {
5965            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5966            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5967                return true;
5968            }
5969            return false;
5970        } catch (ClassCastException e) {
5971        }
5972        return false;
5973    }
5974
5975    @Override
5976    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5977        if (!(pendingResult instanceof PendingIntentRecord)) {
5978            return null;
5979        }
5980        try {
5981            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5982            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5983        } catch (ClassCastException e) {
5984        }
5985        return null;
5986    }
5987
5988    @Override
5989    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5990        if (!(pendingResult instanceof PendingIntentRecord)) {
5991            return null;
5992        }
5993        try {
5994            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5995            Intent intent = res.key.requestIntent;
5996            if (intent != null) {
5997                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5998                        || res.lastTagPrefix.equals(prefix))) {
5999                    return res.lastTag;
6000                }
6001                res.lastTagPrefix = prefix;
6002                StringBuilder sb = new StringBuilder(128);
6003                if (prefix != null) {
6004                    sb.append(prefix);
6005                }
6006                if (intent.getAction() != null) {
6007                    sb.append(intent.getAction());
6008                } else if (intent.getComponent() != null) {
6009                    intent.getComponent().appendShortString(sb);
6010                } else {
6011                    sb.append("?");
6012                }
6013                return res.lastTag = sb.toString();
6014            }
6015        } catch (ClassCastException e) {
6016        }
6017        return null;
6018    }
6019
6020    @Override
6021    public void setProcessLimit(int max) {
6022        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6023                "setProcessLimit()");
6024        synchronized (this) {
6025            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6026            mProcessLimitOverride = max;
6027        }
6028        trimApplications();
6029    }
6030
6031    @Override
6032    public int getProcessLimit() {
6033        synchronized (this) {
6034            return mProcessLimitOverride;
6035        }
6036    }
6037
6038    void foregroundTokenDied(ForegroundToken token) {
6039        synchronized (ActivityManagerService.this) {
6040            synchronized (mPidsSelfLocked) {
6041                ForegroundToken cur
6042                    = mForegroundProcesses.get(token.pid);
6043                if (cur != token) {
6044                    return;
6045                }
6046                mForegroundProcesses.remove(token.pid);
6047                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6048                if (pr == null) {
6049                    return;
6050                }
6051                pr.forcingToForeground = null;
6052                updateProcessForegroundLocked(pr, false, false);
6053            }
6054            updateOomAdjLocked();
6055        }
6056    }
6057
6058    @Override
6059    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6060        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6061                "setProcessForeground()");
6062        synchronized(this) {
6063            boolean changed = false;
6064
6065            synchronized (mPidsSelfLocked) {
6066                ProcessRecord pr = mPidsSelfLocked.get(pid);
6067                if (pr == null && isForeground) {
6068                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6069                    return;
6070                }
6071                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6072                if (oldToken != null) {
6073                    oldToken.token.unlinkToDeath(oldToken, 0);
6074                    mForegroundProcesses.remove(pid);
6075                    if (pr != null) {
6076                        pr.forcingToForeground = null;
6077                    }
6078                    changed = true;
6079                }
6080                if (isForeground && token != null) {
6081                    ForegroundToken newToken = new ForegroundToken() {
6082                        @Override
6083                        public void binderDied() {
6084                            foregroundTokenDied(this);
6085                        }
6086                    };
6087                    newToken.pid = pid;
6088                    newToken.token = token;
6089                    try {
6090                        token.linkToDeath(newToken, 0);
6091                        mForegroundProcesses.put(pid, newToken);
6092                        pr.forcingToForeground = token;
6093                        changed = true;
6094                    } catch (RemoteException e) {
6095                        // If the process died while doing this, we will later
6096                        // do the cleanup with the process death link.
6097                    }
6098                }
6099            }
6100
6101            if (changed) {
6102                updateOomAdjLocked();
6103            }
6104        }
6105    }
6106
6107    // =========================================================
6108    // PERMISSIONS
6109    // =========================================================
6110
6111    static class PermissionController extends IPermissionController.Stub {
6112        ActivityManagerService mActivityManagerService;
6113        PermissionController(ActivityManagerService activityManagerService) {
6114            mActivityManagerService = activityManagerService;
6115        }
6116
6117        @Override
6118        public boolean checkPermission(String permission, int pid, int uid) {
6119            return mActivityManagerService.checkPermission(permission, pid,
6120                    uid) == PackageManager.PERMISSION_GRANTED;
6121        }
6122    }
6123
6124    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6125        @Override
6126        public int checkComponentPermission(String permission, int pid, int uid,
6127                int owningUid, boolean exported) {
6128            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6129                    owningUid, exported);
6130        }
6131
6132        @Override
6133        public Object getAMSLock() {
6134            return ActivityManagerService.this;
6135        }
6136    }
6137
6138    /**
6139     * This can be called with or without the global lock held.
6140     */
6141    int checkComponentPermission(String permission, int pid, int uid,
6142            int owningUid, boolean exported) {
6143        // We might be performing an operation on behalf of an indirect binder
6144        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6145        // client identity accordingly before proceeding.
6146        Identity tlsIdentity = sCallerIdentity.get();
6147        if (tlsIdentity != null) {
6148            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6149                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6150            uid = tlsIdentity.uid;
6151            pid = tlsIdentity.pid;
6152        }
6153
6154        if (pid == MY_PID) {
6155            return PackageManager.PERMISSION_GRANTED;
6156        }
6157
6158        return ActivityManager.checkComponentPermission(permission, uid,
6159                owningUid, exported);
6160    }
6161
6162    /**
6163     * As the only public entry point for permissions checking, this method
6164     * can enforce the semantic that requesting a check on a null global
6165     * permission is automatically denied.  (Internally a null permission
6166     * string is used when calling {@link #checkComponentPermission} in cases
6167     * when only uid-based security is needed.)
6168     *
6169     * This can be called with or without the global lock held.
6170     */
6171    @Override
6172    public int checkPermission(String permission, int pid, int uid) {
6173        if (permission == null) {
6174            return PackageManager.PERMISSION_DENIED;
6175        }
6176        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6177    }
6178
6179    /**
6180     * Binder IPC calls go through the public entry point.
6181     * This can be called with or without the global lock held.
6182     */
6183    int checkCallingPermission(String permission) {
6184        return checkPermission(permission,
6185                Binder.getCallingPid(),
6186                UserHandle.getAppId(Binder.getCallingUid()));
6187    }
6188
6189    /**
6190     * This can be called with or without the global lock held.
6191     */
6192    void enforceCallingPermission(String permission, String func) {
6193        if (checkCallingPermission(permission)
6194                == PackageManager.PERMISSION_GRANTED) {
6195            return;
6196        }
6197
6198        String msg = "Permission Denial: " + func + " from pid="
6199                + Binder.getCallingPid()
6200                + ", uid=" + Binder.getCallingUid()
6201                + " requires " + permission;
6202        Slog.w(TAG, msg);
6203        throw new SecurityException(msg);
6204    }
6205
6206    /**
6207     * Determine if UID is holding permissions required to access {@link Uri} in
6208     * the given {@link ProviderInfo}. Final permission checking is always done
6209     * in {@link ContentProvider}.
6210     */
6211    private final boolean checkHoldingPermissionsLocked(
6212            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6213        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6214                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6215        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6216            return false;
6217        }
6218        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6219    }
6220
6221    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6222            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6223        if (pi.applicationInfo.uid == uid) {
6224            return true;
6225        } else if (!pi.exported) {
6226            return false;
6227        }
6228
6229        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6230        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6231        try {
6232            // check if target holds top-level <provider> permissions
6233            if (!readMet && pi.readPermission != null && considerUidPermissions
6234                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6235                readMet = true;
6236            }
6237            if (!writeMet && pi.writePermission != null && considerUidPermissions
6238                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6239                writeMet = true;
6240            }
6241
6242            // track if unprotected read/write is allowed; any denied
6243            // <path-permission> below removes this ability
6244            boolean allowDefaultRead = pi.readPermission == null;
6245            boolean allowDefaultWrite = pi.writePermission == null;
6246
6247            // check if target holds any <path-permission> that match uri
6248            final PathPermission[] pps = pi.pathPermissions;
6249            if (pps != null) {
6250                final String path = grantUri.uri.getPath();
6251                int i = pps.length;
6252                while (i > 0 && (!readMet || !writeMet)) {
6253                    i--;
6254                    PathPermission pp = pps[i];
6255                    if (pp.match(path)) {
6256                        if (!readMet) {
6257                            final String pprperm = pp.getReadPermission();
6258                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6259                                    + pprperm + " for " + pp.getPath()
6260                                    + ": match=" + pp.match(path)
6261                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6262                            if (pprperm != null) {
6263                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6264                                        == PERMISSION_GRANTED) {
6265                                    readMet = true;
6266                                } else {
6267                                    allowDefaultRead = false;
6268                                }
6269                            }
6270                        }
6271                        if (!writeMet) {
6272                            final String ppwperm = pp.getWritePermission();
6273                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6274                                    + ppwperm + " for " + pp.getPath()
6275                                    + ": match=" + pp.match(path)
6276                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6277                            if (ppwperm != null) {
6278                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6279                                        == PERMISSION_GRANTED) {
6280                                    writeMet = true;
6281                                } else {
6282                                    allowDefaultWrite = false;
6283                                }
6284                            }
6285                        }
6286                    }
6287                }
6288            }
6289
6290            // grant unprotected <provider> read/write, if not blocked by
6291            // <path-permission> above
6292            if (allowDefaultRead) readMet = true;
6293            if (allowDefaultWrite) writeMet = true;
6294
6295        } catch (RemoteException e) {
6296            return false;
6297        }
6298
6299        return readMet && writeMet;
6300    }
6301
6302    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6303        ProviderInfo pi = null;
6304        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6305        if (cpr != null) {
6306            pi = cpr.info;
6307        } else {
6308            try {
6309                pi = AppGlobals.getPackageManager().resolveContentProvider(
6310                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6311            } catch (RemoteException ex) {
6312            }
6313        }
6314        return pi;
6315    }
6316
6317    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6318        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6319        if (targetUris != null) {
6320            return targetUris.get(grantUri);
6321        }
6322        return null;
6323    }
6324
6325    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6326            String targetPkg, int targetUid, GrantUri grantUri) {
6327        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6328        if (targetUris == null) {
6329            targetUris = Maps.newArrayMap();
6330            mGrantedUriPermissions.put(targetUid, targetUris);
6331        }
6332
6333        UriPermission perm = targetUris.get(grantUri);
6334        if (perm == null) {
6335            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6336            targetUris.put(grantUri, perm);
6337        }
6338
6339        return perm;
6340    }
6341
6342    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6343            final int modeFlags) {
6344        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6345        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6346                : UriPermission.STRENGTH_OWNED;
6347
6348        // Root gets to do everything.
6349        if (uid == 0) {
6350            return true;
6351        }
6352
6353        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6354        if (perms == null) return false;
6355
6356        // First look for exact match
6357        final UriPermission exactPerm = perms.get(grantUri);
6358        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6359            return true;
6360        }
6361
6362        // No exact match, look for prefixes
6363        final int N = perms.size();
6364        for (int i = 0; i < N; i++) {
6365            final UriPermission perm = perms.valueAt(i);
6366            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6367                    && perm.getStrength(modeFlags) >= minStrength) {
6368                return true;
6369            }
6370        }
6371
6372        return false;
6373    }
6374
6375    @Override
6376    public int checkUriPermission(Uri uri, int pid, int uid,
6377            final int modeFlags, int userId) {
6378        enforceNotIsolatedCaller("checkUriPermission");
6379
6380        // Another redirected-binder-call permissions check as in
6381        // {@link checkComponentPermission}.
6382        Identity tlsIdentity = sCallerIdentity.get();
6383        if (tlsIdentity != null) {
6384            uid = tlsIdentity.uid;
6385            pid = tlsIdentity.pid;
6386        }
6387
6388        // Our own process gets to do everything.
6389        if (pid == MY_PID) {
6390            return PackageManager.PERMISSION_GRANTED;
6391        }
6392        synchronized (this) {
6393            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6394                    ? PackageManager.PERMISSION_GRANTED
6395                    : PackageManager.PERMISSION_DENIED;
6396        }
6397    }
6398
6399    /**
6400     * Check if the targetPkg can be granted permission to access uri by
6401     * the callingUid using the given modeFlags.  Throws a security exception
6402     * if callingUid is not allowed to do this.  Returns the uid of the target
6403     * if the URI permission grant should be performed; returns -1 if it is not
6404     * needed (for example targetPkg already has permission to access the URI).
6405     * If you already know the uid of the target, you can supply it in
6406     * lastTargetUid else set that to -1.
6407     */
6408    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6409            final int modeFlags, int lastTargetUid) {
6410        if (!Intent.isAccessUriMode(modeFlags)) {
6411            return -1;
6412        }
6413
6414        if (targetPkg != null) {
6415            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6416                    "Checking grant " + targetPkg + " permission to " + grantUri);
6417        }
6418
6419        final IPackageManager pm = AppGlobals.getPackageManager();
6420
6421        // If this is not a content: uri, we can't do anything with it.
6422        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6423            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6424                    "Can't grant URI permission for non-content URI: " + grantUri);
6425            return -1;
6426        }
6427
6428        final String authority = grantUri.uri.getAuthority();
6429        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6430        if (pi == null) {
6431            Slog.w(TAG, "No content provider found for permission check: " +
6432                    grantUri.uri.toSafeString());
6433            return -1;
6434        }
6435
6436        int targetUid = lastTargetUid;
6437        if (targetUid < 0 && targetPkg != null) {
6438            try {
6439                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6440                if (targetUid < 0) {
6441                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6442                            "Can't grant URI permission no uid for: " + targetPkg);
6443                    return -1;
6444                }
6445            } catch (RemoteException ex) {
6446                return -1;
6447            }
6448        }
6449
6450        if (targetUid >= 0) {
6451            // First...  does the target actually need this permission?
6452            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6453                // No need to grant the target this permission.
6454                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6455                        "Target " + targetPkg + " already has full permission to " + grantUri);
6456                return -1;
6457            }
6458        } else {
6459            // First...  there is no target package, so can anyone access it?
6460            boolean allowed = pi.exported;
6461            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6462                if (pi.readPermission != null) {
6463                    allowed = false;
6464                }
6465            }
6466            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6467                if (pi.writePermission != null) {
6468                    allowed = false;
6469                }
6470            }
6471            if (allowed) {
6472                return -1;
6473            }
6474        }
6475
6476        /* There is a special cross user grant if:
6477         * - The target is on another user.
6478         * - Apps on the current user can access the uri without any uid permissions.
6479         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6480         * grant uri permissions.
6481         */
6482        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6483                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6484                modeFlags, false /*without considering the uid permissions*/);
6485
6486        // Second...  is the provider allowing granting of URI permissions?
6487        if (!specialCrossUserGrant) {
6488            if (!pi.grantUriPermissions) {
6489                throw new SecurityException("Provider " + pi.packageName
6490                        + "/" + pi.name
6491                        + " does not allow granting of Uri permissions (uri "
6492                        + grantUri + ")");
6493            }
6494            if (pi.uriPermissionPatterns != null) {
6495                final int N = pi.uriPermissionPatterns.length;
6496                boolean allowed = false;
6497                for (int i=0; i<N; i++) {
6498                    if (pi.uriPermissionPatterns[i] != null
6499                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6500                        allowed = true;
6501                        break;
6502                    }
6503                }
6504                if (!allowed) {
6505                    throw new SecurityException("Provider " + pi.packageName
6506                            + "/" + pi.name
6507                            + " does not allow granting of permission to path of Uri "
6508                            + grantUri);
6509                }
6510            }
6511        }
6512
6513        // Third...  does the caller itself have permission to access
6514        // this uri?
6515        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6516            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6517                // Require they hold a strong enough Uri permission
6518                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6519                    throw new SecurityException("Uid " + callingUid
6520                            + " does not have permission to uri " + grantUri);
6521                }
6522            }
6523        }
6524        return targetUid;
6525    }
6526
6527    @Override
6528    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6529            final int modeFlags, int userId) {
6530        enforceNotIsolatedCaller("checkGrantUriPermission");
6531        synchronized(this) {
6532            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6533                    new GrantUri(userId, uri, false), modeFlags, -1);
6534        }
6535    }
6536
6537    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6538            final int modeFlags, UriPermissionOwner owner) {
6539        if (!Intent.isAccessUriMode(modeFlags)) {
6540            return;
6541        }
6542
6543        // So here we are: the caller has the assumed permission
6544        // to the uri, and the target doesn't.  Let's now give this to
6545        // the target.
6546
6547        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6548                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6549
6550        final String authority = grantUri.uri.getAuthority();
6551        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6552        if (pi == null) {
6553            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6554            return;
6555        }
6556
6557        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6558            grantUri.prefix = true;
6559        }
6560        final UriPermission perm = findOrCreateUriPermissionLocked(
6561                pi.packageName, targetPkg, targetUid, grantUri);
6562        perm.grantModes(modeFlags, owner);
6563    }
6564
6565    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6566            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6567        if (targetPkg == null) {
6568            throw new NullPointerException("targetPkg");
6569        }
6570        int targetUid;
6571        final IPackageManager pm = AppGlobals.getPackageManager();
6572        try {
6573            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6574        } catch (RemoteException ex) {
6575            return;
6576        }
6577
6578        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6579                targetUid);
6580        if (targetUid < 0) {
6581            return;
6582        }
6583
6584        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6585                owner);
6586    }
6587
6588    static class NeededUriGrants extends ArrayList<GrantUri> {
6589        final String targetPkg;
6590        final int targetUid;
6591        final int flags;
6592
6593        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6594            this.targetPkg = targetPkg;
6595            this.targetUid = targetUid;
6596            this.flags = flags;
6597        }
6598    }
6599
6600    /**
6601     * Like checkGrantUriPermissionLocked, but takes an Intent.
6602     */
6603    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6604            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6605        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6606                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6607                + " clip=" + (intent != null ? intent.getClipData() : null)
6608                + " from " + intent + "; flags=0x"
6609                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6610
6611        if (targetPkg == null) {
6612            throw new NullPointerException("targetPkg");
6613        }
6614
6615        if (intent == null) {
6616            return null;
6617        }
6618        Uri data = intent.getData();
6619        ClipData clip = intent.getClipData();
6620        if (data == null && clip == null) {
6621            return null;
6622        }
6623        final IPackageManager pm = AppGlobals.getPackageManager();
6624        int targetUid;
6625        if (needed != null) {
6626            targetUid = needed.targetUid;
6627        } else {
6628            try {
6629                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6630            } catch (RemoteException ex) {
6631                return null;
6632            }
6633            if (targetUid < 0) {
6634                if (DEBUG_URI_PERMISSION) {
6635                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6636                            + " on user " + targetUserId);
6637                }
6638                return null;
6639            }
6640        }
6641        if (data != null) {
6642            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6643            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6644                    targetUid);
6645            if (targetUid > 0) {
6646                if (needed == null) {
6647                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6648                }
6649                needed.add(grantUri);
6650            }
6651        }
6652        if (clip != null) {
6653            for (int i=0; i<clip.getItemCount(); i++) {
6654                Uri uri = clip.getItemAt(i).getUri();
6655                if (uri != null) {
6656                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6657                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6658                            targetUid);
6659                    if (targetUid > 0) {
6660                        if (needed == null) {
6661                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6662                        }
6663                        needed.add(grantUri);
6664                    }
6665                } else {
6666                    Intent clipIntent = clip.getItemAt(i).getIntent();
6667                    if (clipIntent != null) {
6668                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6669                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6670                        if (newNeeded != null) {
6671                            needed = newNeeded;
6672                        }
6673                    }
6674                }
6675            }
6676        }
6677
6678        return needed;
6679    }
6680
6681    /**
6682     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6683     */
6684    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6685            UriPermissionOwner owner) {
6686        if (needed != null) {
6687            for (int i=0; i<needed.size(); i++) {
6688                GrantUri grantUri = needed.get(i);
6689                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6690                        grantUri, needed.flags, owner);
6691            }
6692        }
6693    }
6694
6695    void grantUriPermissionFromIntentLocked(int callingUid,
6696            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6697        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6698                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6699        if (needed == null) {
6700            return;
6701        }
6702
6703        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6704    }
6705
6706    @Override
6707    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6708            final int modeFlags, int userId) {
6709        enforceNotIsolatedCaller("grantUriPermission");
6710        GrantUri grantUri = new GrantUri(userId, uri, false);
6711        synchronized(this) {
6712            final ProcessRecord r = getRecordForAppLocked(caller);
6713            if (r == null) {
6714                throw new SecurityException("Unable to find app for caller "
6715                        + caller
6716                        + " when granting permission to uri " + grantUri);
6717            }
6718            if (targetPkg == null) {
6719                throw new IllegalArgumentException("null target");
6720            }
6721            if (grantUri == null) {
6722                throw new IllegalArgumentException("null uri");
6723            }
6724
6725            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6726                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6727                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6728                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6729
6730            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6731                    UserHandle.getUserId(r.uid));
6732        }
6733    }
6734
6735    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6736        if (perm.modeFlags == 0) {
6737            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6738                    perm.targetUid);
6739            if (perms != null) {
6740                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6741                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6742
6743                perms.remove(perm.uri);
6744                if (perms.isEmpty()) {
6745                    mGrantedUriPermissions.remove(perm.targetUid);
6746                }
6747            }
6748        }
6749    }
6750
6751    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6752        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6753
6754        final IPackageManager pm = AppGlobals.getPackageManager();
6755        final String authority = grantUri.uri.getAuthority();
6756        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6757        if (pi == null) {
6758            Slog.w(TAG, "No content provider found for permission revoke: "
6759                    + grantUri.toSafeString());
6760            return;
6761        }
6762
6763        // Does the caller have this permission on the URI?
6764        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6765            // Right now, if you are not the original owner of the permission,
6766            // you are not allowed to revoke it.
6767            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6768                throw new SecurityException("Uid " + callingUid
6769                        + " does not have permission to uri " + grantUri);
6770            //}
6771        }
6772
6773        boolean persistChanged = false;
6774
6775        // Go through all of the permissions and remove any that match.
6776        int N = mGrantedUriPermissions.size();
6777        for (int i = 0; i < N; i++) {
6778            final int targetUid = mGrantedUriPermissions.keyAt(i);
6779            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6780
6781            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6782                final UriPermission perm = it.next();
6783                if (perm.uri.sourceUserId == grantUri.sourceUserId
6784                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6785                    if (DEBUG_URI_PERMISSION)
6786                        Slog.v(TAG,
6787                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6788                    persistChanged |= perm.revokeModes(
6789                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6790                    if (perm.modeFlags == 0) {
6791                        it.remove();
6792                    }
6793                }
6794            }
6795
6796            if (perms.isEmpty()) {
6797                mGrantedUriPermissions.remove(targetUid);
6798                N--;
6799                i--;
6800            }
6801        }
6802
6803        if (persistChanged) {
6804            schedulePersistUriGrants();
6805        }
6806    }
6807
6808    @Override
6809    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6810            int userId) {
6811        enforceNotIsolatedCaller("revokeUriPermission");
6812        synchronized(this) {
6813            final ProcessRecord r = getRecordForAppLocked(caller);
6814            if (r == null) {
6815                throw new SecurityException("Unable to find app for caller "
6816                        + caller
6817                        + " when revoking permission to uri " + uri);
6818            }
6819            if (uri == null) {
6820                Slog.w(TAG, "revokeUriPermission: null uri");
6821                return;
6822            }
6823
6824            if (!Intent.isAccessUriMode(modeFlags)) {
6825                return;
6826            }
6827
6828            final IPackageManager pm = AppGlobals.getPackageManager();
6829            final String authority = uri.getAuthority();
6830            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6831            if (pi == null) {
6832                Slog.w(TAG, "No content provider found for permission revoke: "
6833                        + uri.toSafeString());
6834                return;
6835            }
6836
6837            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6838        }
6839    }
6840
6841    /**
6842     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6843     * given package.
6844     *
6845     * @param packageName Package name to match, or {@code null} to apply to all
6846     *            packages.
6847     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6848     *            to all users.
6849     * @param persistable If persistable grants should be removed.
6850     */
6851    private void removeUriPermissionsForPackageLocked(
6852            String packageName, int userHandle, boolean persistable) {
6853        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6854            throw new IllegalArgumentException("Must narrow by either package or user");
6855        }
6856
6857        boolean persistChanged = false;
6858
6859        int N = mGrantedUriPermissions.size();
6860        for (int i = 0; i < N; i++) {
6861            final int targetUid = mGrantedUriPermissions.keyAt(i);
6862            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6863
6864            // Only inspect grants matching user
6865            if (userHandle == UserHandle.USER_ALL
6866                    || userHandle == UserHandle.getUserId(targetUid)) {
6867                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6868                    final UriPermission perm = it.next();
6869
6870                    // Only inspect grants matching package
6871                    if (packageName == null || perm.sourcePkg.equals(packageName)
6872                            || perm.targetPkg.equals(packageName)) {
6873                        persistChanged |= perm.revokeModes(
6874                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6875
6876                        // Only remove when no modes remain; any persisted grants
6877                        // will keep this alive.
6878                        if (perm.modeFlags == 0) {
6879                            it.remove();
6880                        }
6881                    }
6882                }
6883
6884                if (perms.isEmpty()) {
6885                    mGrantedUriPermissions.remove(targetUid);
6886                    N--;
6887                    i--;
6888                }
6889            }
6890        }
6891
6892        if (persistChanged) {
6893            schedulePersistUriGrants();
6894        }
6895    }
6896
6897    @Override
6898    public IBinder newUriPermissionOwner(String name) {
6899        enforceNotIsolatedCaller("newUriPermissionOwner");
6900        synchronized(this) {
6901            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6902            return owner.getExternalTokenLocked();
6903        }
6904    }
6905
6906    @Override
6907    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6908            final int modeFlags, int sourceUserId, int targetUserId) {
6909        synchronized(this) {
6910            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6911            if (owner == null) {
6912                throw new IllegalArgumentException("Unknown owner: " + token);
6913            }
6914            if (fromUid != Binder.getCallingUid()) {
6915                if (Binder.getCallingUid() != Process.myUid()) {
6916                    // Only system code can grant URI permissions on behalf
6917                    // of other users.
6918                    throw new SecurityException("nice try");
6919                }
6920            }
6921            if (targetPkg == null) {
6922                throw new IllegalArgumentException("null target");
6923            }
6924            if (uri == null) {
6925                throw new IllegalArgumentException("null uri");
6926            }
6927
6928            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6929                    modeFlags, owner, targetUserId);
6930        }
6931    }
6932
6933    @Override
6934    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6935        synchronized(this) {
6936            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6937            if (owner == null) {
6938                throw new IllegalArgumentException("Unknown owner: " + token);
6939            }
6940
6941            if (uri == null) {
6942                owner.removeUriPermissionsLocked(mode);
6943            } else {
6944                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6945            }
6946        }
6947    }
6948
6949    private void schedulePersistUriGrants() {
6950        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6951            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6952                    10 * DateUtils.SECOND_IN_MILLIS);
6953        }
6954    }
6955
6956    private void writeGrantedUriPermissions() {
6957        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6958
6959        // Snapshot permissions so we can persist without lock
6960        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6961        synchronized (this) {
6962            final int size = mGrantedUriPermissions.size();
6963            for (int i = 0; i < size; i++) {
6964                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6965                for (UriPermission perm : perms.values()) {
6966                    if (perm.persistedModeFlags != 0) {
6967                        persist.add(perm.snapshot());
6968                    }
6969                }
6970            }
6971        }
6972
6973        FileOutputStream fos = null;
6974        try {
6975            fos = mGrantFile.startWrite();
6976
6977            XmlSerializer out = new FastXmlSerializer();
6978            out.setOutput(fos, "utf-8");
6979            out.startDocument(null, true);
6980            out.startTag(null, TAG_URI_GRANTS);
6981            for (UriPermission.Snapshot perm : persist) {
6982                out.startTag(null, TAG_URI_GRANT);
6983                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6984                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6985                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6986                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6987                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6988                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6989                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6990                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6991                out.endTag(null, TAG_URI_GRANT);
6992            }
6993            out.endTag(null, TAG_URI_GRANTS);
6994            out.endDocument();
6995
6996            mGrantFile.finishWrite(fos);
6997        } catch (IOException e) {
6998            if (fos != null) {
6999                mGrantFile.failWrite(fos);
7000            }
7001        }
7002    }
7003
7004    private void readGrantedUriPermissionsLocked() {
7005        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7006
7007        final long now = System.currentTimeMillis();
7008
7009        FileInputStream fis = null;
7010        try {
7011            fis = mGrantFile.openRead();
7012            final XmlPullParser in = Xml.newPullParser();
7013            in.setInput(fis, null);
7014
7015            int type;
7016            while ((type = in.next()) != END_DOCUMENT) {
7017                final String tag = in.getName();
7018                if (type == START_TAG) {
7019                    if (TAG_URI_GRANT.equals(tag)) {
7020                        final int sourceUserId;
7021                        final int targetUserId;
7022                        final int userHandle = readIntAttribute(in,
7023                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7024                        if (userHandle != UserHandle.USER_NULL) {
7025                            // For backwards compatibility.
7026                            sourceUserId = userHandle;
7027                            targetUserId = userHandle;
7028                        } else {
7029                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7030                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7031                        }
7032                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7033                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7034                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7035                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7036                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7037                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7038
7039                        // Sanity check that provider still belongs to source package
7040                        final ProviderInfo pi = getProviderInfoLocked(
7041                                uri.getAuthority(), sourceUserId);
7042                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7043                            int targetUid = -1;
7044                            try {
7045                                targetUid = AppGlobals.getPackageManager()
7046                                        .getPackageUid(targetPkg, targetUserId);
7047                            } catch (RemoteException e) {
7048                            }
7049                            if (targetUid != -1) {
7050                                final UriPermission perm = findOrCreateUriPermissionLocked(
7051                                        sourcePkg, targetPkg, targetUid,
7052                                        new GrantUri(sourceUserId, uri, prefix));
7053                                perm.initPersistedModes(modeFlags, createdTime);
7054                            }
7055                        } else {
7056                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7057                                    + " but instead found " + pi);
7058                        }
7059                    }
7060                }
7061            }
7062        } catch (FileNotFoundException e) {
7063            // Missing grants is okay
7064        } catch (IOException e) {
7065            Log.wtf(TAG, "Failed reading Uri grants", e);
7066        } catch (XmlPullParserException e) {
7067            Log.wtf(TAG, "Failed reading Uri grants", e);
7068        } finally {
7069            IoUtils.closeQuietly(fis);
7070        }
7071    }
7072
7073    @Override
7074    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7075        enforceNotIsolatedCaller("takePersistableUriPermission");
7076
7077        Preconditions.checkFlagsArgument(modeFlags,
7078                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7079
7080        synchronized (this) {
7081            final int callingUid = Binder.getCallingUid();
7082            boolean persistChanged = false;
7083            GrantUri grantUri = new GrantUri(userId, uri, false);
7084
7085            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7086                    new GrantUri(userId, uri, false));
7087            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7088                    new GrantUri(userId, uri, true));
7089
7090            final boolean exactValid = (exactPerm != null)
7091                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7092            final boolean prefixValid = (prefixPerm != null)
7093                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7094
7095            if (!(exactValid || prefixValid)) {
7096                throw new SecurityException("No persistable permission grants found for UID "
7097                        + callingUid + " and Uri " + grantUri.toSafeString());
7098            }
7099
7100            if (exactValid) {
7101                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7102            }
7103            if (prefixValid) {
7104                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7105            }
7106
7107            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7108
7109            if (persistChanged) {
7110                schedulePersistUriGrants();
7111            }
7112        }
7113    }
7114
7115    @Override
7116    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7117        enforceNotIsolatedCaller("releasePersistableUriPermission");
7118
7119        Preconditions.checkFlagsArgument(modeFlags,
7120                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7121
7122        synchronized (this) {
7123            final int callingUid = Binder.getCallingUid();
7124            boolean persistChanged = false;
7125
7126            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7127                    new GrantUri(userId, uri, false));
7128            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7129                    new GrantUri(userId, uri, true));
7130            if (exactPerm == null && prefixPerm == null) {
7131                throw new SecurityException("No permission grants found for UID " + callingUid
7132                        + " and Uri " + uri.toSafeString());
7133            }
7134
7135            if (exactPerm != null) {
7136                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7137                removeUriPermissionIfNeededLocked(exactPerm);
7138            }
7139            if (prefixPerm != null) {
7140                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7141                removeUriPermissionIfNeededLocked(prefixPerm);
7142            }
7143
7144            if (persistChanged) {
7145                schedulePersistUriGrants();
7146            }
7147        }
7148    }
7149
7150    /**
7151     * Prune any older {@link UriPermission} for the given UID until outstanding
7152     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7153     *
7154     * @return if any mutations occured that require persisting.
7155     */
7156    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7157        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7158        if (perms == null) return false;
7159        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7160
7161        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7162        for (UriPermission perm : perms.values()) {
7163            if (perm.persistedModeFlags != 0) {
7164                persisted.add(perm);
7165            }
7166        }
7167
7168        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7169        if (trimCount <= 0) return false;
7170
7171        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7172        for (int i = 0; i < trimCount; i++) {
7173            final UriPermission perm = persisted.get(i);
7174
7175            if (DEBUG_URI_PERMISSION) {
7176                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7177            }
7178
7179            perm.releasePersistableModes(~0);
7180            removeUriPermissionIfNeededLocked(perm);
7181        }
7182
7183        return true;
7184    }
7185
7186    @Override
7187    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7188            String packageName, boolean incoming) {
7189        enforceNotIsolatedCaller("getPersistedUriPermissions");
7190        Preconditions.checkNotNull(packageName, "packageName");
7191
7192        final int callingUid = Binder.getCallingUid();
7193        final IPackageManager pm = AppGlobals.getPackageManager();
7194        try {
7195            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7196            if (packageUid != callingUid) {
7197                throw new SecurityException(
7198                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7199            }
7200        } catch (RemoteException e) {
7201            throw new SecurityException("Failed to verify package name ownership");
7202        }
7203
7204        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7205        synchronized (this) {
7206            if (incoming) {
7207                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7208                        callingUid);
7209                if (perms == null) {
7210                    Slog.w(TAG, "No permission grants found for " + packageName);
7211                } else {
7212                    for (UriPermission perm : perms.values()) {
7213                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7214                            result.add(perm.buildPersistedPublicApiObject());
7215                        }
7216                    }
7217                }
7218            } else {
7219                final int size = mGrantedUriPermissions.size();
7220                for (int i = 0; i < size; i++) {
7221                    final ArrayMap<GrantUri, UriPermission> perms =
7222                            mGrantedUriPermissions.valueAt(i);
7223                    for (UriPermission perm : perms.values()) {
7224                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7225                            result.add(perm.buildPersistedPublicApiObject());
7226                        }
7227                    }
7228                }
7229            }
7230        }
7231        return new ParceledListSlice<android.content.UriPermission>(result);
7232    }
7233
7234    @Override
7235    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7236        synchronized (this) {
7237            ProcessRecord app =
7238                who != null ? getRecordForAppLocked(who) : null;
7239            if (app == null) return;
7240
7241            Message msg = Message.obtain();
7242            msg.what = WAIT_FOR_DEBUGGER_MSG;
7243            msg.obj = app;
7244            msg.arg1 = waiting ? 1 : 0;
7245            mHandler.sendMessage(msg);
7246        }
7247    }
7248
7249    @Override
7250    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7251        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7252        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7253        outInfo.availMem = Process.getFreeMemory();
7254        outInfo.totalMem = Process.getTotalMemory();
7255        outInfo.threshold = homeAppMem;
7256        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7257        outInfo.hiddenAppThreshold = cachedAppMem;
7258        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7259                ProcessList.SERVICE_ADJ);
7260        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7261                ProcessList.VISIBLE_APP_ADJ);
7262        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7263                ProcessList.FOREGROUND_APP_ADJ);
7264    }
7265
7266    // =========================================================
7267    // TASK MANAGEMENT
7268    // =========================================================
7269
7270    @Override
7271    public List<IAppTask> getAppTasks() {
7272        final PackageManager pm = mContext.getPackageManager();
7273        int callingUid = Binder.getCallingUid();
7274        long ident = Binder.clearCallingIdentity();
7275
7276        // Compose the list of packages for this id to test against
7277        HashSet<String> packages = new HashSet<String>();
7278        String[] uidPackages = pm.getPackagesForUid(callingUid);
7279        for (int i = 0; i < uidPackages.length; i++) {
7280            packages.add(uidPackages[i]);
7281        }
7282
7283        synchronized(this) {
7284            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7285            try {
7286                if (localLOGV) Slog.v(TAG, "getAppTasks");
7287
7288                final int N = mRecentTasks.size();
7289                for (int i = 0; i < N; i++) {
7290                    TaskRecord tr = mRecentTasks.get(i);
7291                    // Skip tasks that are not created by the caller
7292                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7293                        ActivityManager.RecentTaskInfo taskInfo =
7294                                createRecentTaskInfoFromTaskRecord(tr);
7295                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7296                        list.add(taskImpl);
7297                    }
7298                }
7299            } finally {
7300                Binder.restoreCallingIdentity(ident);
7301            }
7302            return list;
7303        }
7304    }
7305
7306    @Override
7307    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7308        final int callingUid = Binder.getCallingUid();
7309        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7310
7311        synchronized(this) {
7312            if (localLOGV) Slog.v(
7313                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7314
7315            final boolean allowed = checkCallingPermission(
7316                    android.Manifest.permission.GET_TASKS)
7317                    == PackageManager.PERMISSION_GRANTED;
7318            if (!allowed) {
7319                Slog.w(TAG, "getTasks: caller " + callingUid
7320                        + " does not hold GET_TASKS; limiting output");
7321            }
7322
7323            // TODO: Improve with MRU list from all ActivityStacks.
7324            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7325        }
7326
7327        return list;
7328    }
7329
7330    TaskRecord getMostRecentTask() {
7331        return mRecentTasks.get(0);
7332    }
7333
7334    /**
7335     * Creates a new RecentTaskInfo from a TaskRecord.
7336     */
7337    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7338        // Update the task description to reflect any changes in the task stack
7339        tr.updateTaskDescription();
7340
7341        // Compose the recent task info
7342        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7343        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7344        rti.persistentId = tr.taskId;
7345        rti.baseIntent = new Intent(tr.getBaseIntent());
7346        rti.origActivity = tr.origActivity;
7347        rti.description = tr.lastDescription;
7348        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7349        rti.userId = tr.userId;
7350        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7351        rti.firstActiveTime = tr.firstActiveTime;
7352        rti.lastActiveTime = tr.lastActiveTime;
7353        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7354        return rti;
7355    }
7356
7357    @Override
7358    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7359        final int callingUid = Binder.getCallingUid();
7360        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7361                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7362
7363        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7364        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7365        synchronized (this) {
7366            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7367                    == PackageManager.PERMISSION_GRANTED;
7368            if (!allowed) {
7369                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7370                        + " does not hold GET_TASKS; limiting output");
7371            }
7372            final boolean detailed = checkCallingPermission(
7373                    android.Manifest.permission.GET_DETAILED_TASKS)
7374                    == PackageManager.PERMISSION_GRANTED;
7375
7376            IPackageManager pm = AppGlobals.getPackageManager();
7377
7378            final int N = mRecentTasks.size();
7379            ArrayList<ActivityManager.RecentTaskInfo> res
7380                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7381                            maxNum < N ? maxNum : N);
7382
7383            final Set<Integer> includedUsers;
7384            if (includeProfiles) {
7385                includedUsers = getProfileIdsLocked(userId);
7386            } else {
7387                includedUsers = new HashSet<Integer>();
7388            }
7389            includedUsers.add(Integer.valueOf(userId));
7390
7391            // Regroup affiliated tasks together.
7392            for (int i = 0; i < N; ) {
7393                TaskRecord task = mRecentTasks.remove(i);
7394                if (mTmpRecents.contains(task)) {
7395                    continue;
7396                }
7397                int affiliatedTaskId = task.mAffiliatedTaskId;
7398                while (true) {
7399                    TaskRecord next = task.mNextAffiliate;
7400                    if (next == null) {
7401                        break;
7402                    }
7403                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7404                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7405                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7406                        task.setNextAffiliate(null);
7407                        if (next.mPrevAffiliate == task) {
7408                            next.setPrevAffiliate(null);
7409                        }
7410                        break;
7411                    }
7412                    if (next.mPrevAffiliate != task) {
7413                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7414                                next.mPrevAffiliate + " task=" + task);
7415                        next.setPrevAffiliate(null);
7416                        break;
7417                    }
7418                    if (!mRecentTasks.contains(next)) {
7419                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7420                        task.setNextAffiliate(null);
7421                        if (next.mPrevAffiliate == task) {
7422                            next.setPrevAffiliate(null);
7423                        }
7424                        break;
7425                    }
7426                    task = next;
7427                }
7428                // task is now the end of the list
7429                do {
7430                    mRecentTasks.remove(task);
7431                    mRecentTasks.add(i++, task);
7432                    mTmpRecents.add(task);
7433                } while ((task = task.mPrevAffiliate) != null);
7434            }
7435            mTmpRecents.clear();
7436            // mRecentTasks is now in sorted, affiliated order.
7437
7438            for (int i=0; i<N && maxNum > 0; i++) {
7439                TaskRecord tr = mRecentTasks.get(i);
7440                // Only add calling user or related users recent tasks
7441                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7442
7443                // Return the entry if desired by the caller.  We always return
7444                // the first entry, because callers always expect this to be the
7445                // foreground app.  We may filter others if the caller has
7446                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7447                // we should exclude the entry.
7448
7449                if (i == 0
7450                        || withExcluded
7451                        || (tr.intent == null)
7452                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7453                                == 0)) {
7454                    if (!allowed) {
7455                        // If the caller doesn't have the GET_TASKS permission, then only
7456                        // allow them to see a small subset of tasks -- their own and home.
7457                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7458                            continue;
7459                        }
7460                    }
7461                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7462                        // Don't include auto remove tasks that are finished or finishing.
7463                        continue;
7464                    }
7465
7466                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7467                    if (!detailed) {
7468                        rti.baseIntent.replaceExtras((Bundle)null);
7469                    }
7470
7471                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7472                        // Check whether this activity is currently available.
7473                        try {
7474                            if (rti.origActivity != null) {
7475                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7476                                        == null) {
7477                                    continue;
7478                                }
7479                            } else if (rti.baseIntent != null) {
7480                                if (pm.queryIntentActivities(rti.baseIntent,
7481                                        null, 0, userId) == null) {
7482                                    continue;
7483                                }
7484                            }
7485                        } catch (RemoteException e) {
7486                            // Will never happen.
7487                        }
7488                    }
7489
7490                    res.add(rti);
7491                    maxNum--;
7492                }
7493            }
7494            return res;
7495        }
7496    }
7497
7498    private TaskRecord recentTaskForIdLocked(int id) {
7499        final int N = mRecentTasks.size();
7500            for (int i=0; i<N; i++) {
7501                TaskRecord tr = mRecentTasks.get(i);
7502                if (tr.taskId == id) {
7503                    return tr;
7504                }
7505            }
7506            return null;
7507    }
7508
7509    @Override
7510    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7511        synchronized (this) {
7512            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7513                    "getTaskThumbnail()");
7514            TaskRecord tr = recentTaskForIdLocked(id);
7515            if (tr != null) {
7516                return tr.getTaskThumbnailLocked();
7517            }
7518        }
7519        return null;
7520    }
7521
7522    @Override
7523    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7524        synchronized (this) {
7525            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7526            if (r != null) {
7527                r.taskDescription = td;
7528                r.task.updateTaskDescription();
7529            }
7530        }
7531    }
7532
7533    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7534        if (!pr.killedByAm) {
7535            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7536            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7537                    pr.processName, pr.setAdj, reason);
7538            pr.killedByAm = true;
7539            Process.killProcessQuiet(pr.pid);
7540            Process.killProcessGroup(pr.info.uid, pr.pid);
7541        }
7542    }
7543
7544    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7545        tr.disposeThumbnail();
7546        mRecentTasks.remove(tr);
7547        tr.closeRecentsChain();
7548        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7549        Intent baseIntent = new Intent(
7550                tr.intent != null ? tr.intent : tr.affinityIntent);
7551        ComponentName component = baseIntent.getComponent();
7552        if (component == null) {
7553            Slog.w(TAG, "Now component for base intent of task: " + tr);
7554            return;
7555        }
7556
7557        // Find any running services associated with this app.
7558        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7559
7560        if (killProcesses) {
7561            // Find any running processes associated with this app.
7562            final String pkg = component.getPackageName();
7563            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7564            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7565            for (int i=0; i<pmap.size(); i++) {
7566                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7567                for (int j=0; j<uids.size(); j++) {
7568                    ProcessRecord proc = uids.valueAt(j);
7569                    if (proc.userId != tr.userId) {
7570                        continue;
7571                    }
7572                    if (!proc.pkgList.containsKey(pkg)) {
7573                        continue;
7574                    }
7575                    procs.add(proc);
7576                }
7577            }
7578
7579            // Kill the running processes.
7580            for (int i=0; i<procs.size(); i++) {
7581                ProcessRecord pr = procs.get(i);
7582                if (pr == mHomeProcess) {
7583                    // Don't kill the home process along with tasks from the same package.
7584                    continue;
7585                }
7586                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7587                    killUnneededProcessLocked(pr, "remove task");
7588                } else {
7589                    pr.waitingToKill = "remove task";
7590                }
7591            }
7592        }
7593    }
7594
7595    /**
7596     * Removes the task with the specified task id.
7597     *
7598     * @param taskId Identifier of the task to be removed.
7599     * @param flags Additional operational flags.  May be 0 or
7600     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7601     * @return Returns true if the given task was found and removed.
7602     */
7603    private boolean removeTaskByIdLocked(int taskId, int flags) {
7604        TaskRecord tr = recentTaskForIdLocked(taskId);
7605        if (tr != null) {
7606            tr.removeTaskActivitiesLocked();
7607            cleanUpRemovedTaskLocked(tr, flags);
7608            if (tr.isPersistable) {
7609                notifyTaskPersisterLocked(tr, true);
7610            }
7611            return true;
7612        }
7613        return false;
7614    }
7615
7616    @Override
7617    public boolean removeTask(int taskId, int flags) {
7618        synchronized (this) {
7619            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7620                    "removeTask()");
7621            long ident = Binder.clearCallingIdentity();
7622            try {
7623                return removeTaskByIdLocked(taskId, flags);
7624            } finally {
7625                Binder.restoreCallingIdentity(ident);
7626            }
7627        }
7628    }
7629
7630    /**
7631     * TODO: Add mController hook
7632     */
7633    @Override
7634    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7635        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7636                "moveTaskToFront()");
7637
7638        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7639        synchronized(this) {
7640            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7641                    Binder.getCallingUid(), "Task to front")) {
7642                ActivityOptions.abort(options);
7643                return;
7644            }
7645            final long origId = Binder.clearCallingIdentity();
7646            try {
7647                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7648                if (task == null) {
7649                    return;
7650                }
7651                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7652                    mStackSupervisor.showLockTaskToast();
7653                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7654                    return;
7655                }
7656                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7657                if (prev != null && prev.isRecentsActivity()) {
7658                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7659                }
7660                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7661            } finally {
7662                Binder.restoreCallingIdentity(origId);
7663            }
7664            ActivityOptions.abort(options);
7665        }
7666    }
7667
7668    @Override
7669    public void moveTaskToBack(int taskId) {
7670        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7671                "moveTaskToBack()");
7672
7673        synchronized(this) {
7674            TaskRecord tr = recentTaskForIdLocked(taskId);
7675            if (tr != null) {
7676                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7677                ActivityStack stack = tr.stack;
7678                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7679                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7680                            Binder.getCallingUid(), "Task to back")) {
7681                        return;
7682                    }
7683                }
7684                final long origId = Binder.clearCallingIdentity();
7685                try {
7686                    stack.moveTaskToBackLocked(taskId, null);
7687                } finally {
7688                    Binder.restoreCallingIdentity(origId);
7689                }
7690            }
7691        }
7692    }
7693
7694    /**
7695     * Moves an activity, and all of the other activities within the same task, to the bottom
7696     * of the history stack.  The activity's order within the task is unchanged.
7697     *
7698     * @param token A reference to the activity we wish to move
7699     * @param nonRoot If false then this only works if the activity is the root
7700     *                of a task; if true it will work for any activity in a task.
7701     * @return Returns true if the move completed, false if not.
7702     */
7703    @Override
7704    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7705        enforceNotIsolatedCaller("moveActivityTaskToBack");
7706        synchronized(this) {
7707            final long origId = Binder.clearCallingIdentity();
7708            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7709            if (taskId >= 0) {
7710                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7711            }
7712            Binder.restoreCallingIdentity(origId);
7713        }
7714        return false;
7715    }
7716
7717    @Override
7718    public void moveTaskBackwards(int task) {
7719        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7720                "moveTaskBackwards()");
7721
7722        synchronized(this) {
7723            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7724                    Binder.getCallingUid(), "Task backwards")) {
7725                return;
7726            }
7727            final long origId = Binder.clearCallingIdentity();
7728            moveTaskBackwardsLocked(task);
7729            Binder.restoreCallingIdentity(origId);
7730        }
7731    }
7732
7733    private final void moveTaskBackwardsLocked(int task) {
7734        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7735    }
7736
7737    @Override
7738    public IBinder getHomeActivityToken() throws RemoteException {
7739        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7740                "getHomeActivityToken()");
7741        synchronized (this) {
7742            return mStackSupervisor.getHomeActivityToken();
7743        }
7744    }
7745
7746    @Override
7747    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7748            IActivityContainerCallback callback) throws RemoteException {
7749        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7750                "createActivityContainer()");
7751        synchronized (this) {
7752            if (parentActivityToken == null) {
7753                throw new IllegalArgumentException("parent token must not be null");
7754            }
7755            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7756            if (r == null) {
7757                return null;
7758            }
7759            if (callback == null) {
7760                throw new IllegalArgumentException("callback must not be null");
7761            }
7762            return mStackSupervisor.createActivityContainer(r, callback);
7763        }
7764    }
7765
7766    @Override
7767    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7768        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7769                "deleteActivityContainer()");
7770        synchronized (this) {
7771            mStackSupervisor.deleteActivityContainer(container);
7772        }
7773    }
7774
7775    @Override
7776    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7777            throws RemoteException {
7778        synchronized (this) {
7779            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7780            if (stack != null) {
7781                return stack.mActivityContainer;
7782            }
7783            return null;
7784        }
7785    }
7786
7787    @Override
7788    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7789        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7790                "moveTaskToStack()");
7791        if (stackId == HOME_STACK_ID) {
7792            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7793                    new RuntimeException("here").fillInStackTrace());
7794        }
7795        synchronized (this) {
7796            long ident = Binder.clearCallingIdentity();
7797            try {
7798                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7799                        + stackId + " toTop=" + toTop);
7800                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7801            } finally {
7802                Binder.restoreCallingIdentity(ident);
7803            }
7804        }
7805    }
7806
7807    @Override
7808    public void resizeStack(int stackBoxId, Rect bounds) {
7809        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7810                "resizeStackBox()");
7811        long ident = Binder.clearCallingIdentity();
7812        try {
7813            mWindowManager.resizeStack(stackBoxId, bounds);
7814        } finally {
7815            Binder.restoreCallingIdentity(ident);
7816        }
7817    }
7818
7819    @Override
7820    public List<StackInfo> getAllStackInfos() {
7821        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7822                "getAllStackInfos()");
7823        long ident = Binder.clearCallingIdentity();
7824        try {
7825            synchronized (this) {
7826                return mStackSupervisor.getAllStackInfosLocked();
7827            }
7828        } finally {
7829            Binder.restoreCallingIdentity(ident);
7830        }
7831    }
7832
7833    @Override
7834    public StackInfo getStackInfo(int stackId) {
7835        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7836                "getStackInfo()");
7837        long ident = Binder.clearCallingIdentity();
7838        try {
7839            synchronized (this) {
7840                return mStackSupervisor.getStackInfoLocked(stackId);
7841            }
7842        } finally {
7843            Binder.restoreCallingIdentity(ident);
7844        }
7845    }
7846
7847    @Override
7848    public boolean isInHomeStack(int taskId) {
7849        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7850                "getStackInfo()");
7851        long ident = Binder.clearCallingIdentity();
7852        try {
7853            synchronized (this) {
7854                TaskRecord tr = recentTaskForIdLocked(taskId);
7855                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7856            }
7857        } finally {
7858            Binder.restoreCallingIdentity(ident);
7859        }
7860    }
7861
7862    @Override
7863    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7864        synchronized(this) {
7865            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7866        }
7867    }
7868
7869    private boolean isLockTaskAuthorized(String pkg) {
7870        final DevicePolicyManager dpm = (DevicePolicyManager)
7871                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7872        try {
7873            int uid = mContext.getPackageManager().getPackageUid(pkg,
7874                    Binder.getCallingUserHandle().getIdentifier());
7875            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7876        } catch (NameNotFoundException e) {
7877            return false;
7878        }
7879    }
7880
7881    void startLockTaskMode(TaskRecord task) {
7882        final String pkg;
7883        synchronized (this) {
7884            pkg = task.intent.getComponent().getPackageName();
7885        }
7886        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7887        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7888            final TaskRecord taskRecord = task;
7889            mHandler.post(new Runnable() {
7890                @Override
7891                public void run() {
7892                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7893                }
7894            });
7895            return;
7896        }
7897        long ident = Binder.clearCallingIdentity();
7898        try {
7899            synchronized (this) {
7900                // Since we lost lock on task, make sure it is still there.
7901                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7902                if (task != null) {
7903                    if (!isSystemInitiated
7904                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7905                        throw new IllegalArgumentException("Invalid task, not in foreground");
7906                    }
7907                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7908                }
7909            }
7910        } finally {
7911            Binder.restoreCallingIdentity(ident);
7912        }
7913    }
7914
7915    @Override
7916    public void startLockTaskMode(int taskId) {
7917        final TaskRecord task;
7918        long ident = Binder.clearCallingIdentity();
7919        try {
7920            synchronized (this) {
7921                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7922            }
7923        } finally {
7924            Binder.restoreCallingIdentity(ident);
7925        }
7926        if (task != null) {
7927            startLockTaskMode(task);
7928        }
7929    }
7930
7931    @Override
7932    public void startLockTaskMode(IBinder token) {
7933        final TaskRecord task;
7934        long ident = Binder.clearCallingIdentity();
7935        try {
7936            synchronized (this) {
7937                final ActivityRecord r = ActivityRecord.forToken(token);
7938                if (r == null) {
7939                    return;
7940                }
7941                task = r.task;
7942            }
7943        } finally {
7944            Binder.restoreCallingIdentity(ident);
7945        }
7946        if (task != null) {
7947            startLockTaskMode(task);
7948        }
7949    }
7950
7951    @Override
7952    public void startLockTaskModeOnCurrent() throws RemoteException {
7953        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7954        ActivityRecord r = null;
7955        synchronized (this) {
7956            r = mStackSupervisor.topRunningActivityLocked();
7957        }
7958        startLockTaskMode(r.task);
7959    }
7960
7961    @Override
7962    public void stopLockTaskMode() {
7963        // Verify that the user matches the package of the intent for the TaskRecord
7964        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7965        // and stopLockTaskMode.
7966        final int callingUid = Binder.getCallingUid();
7967        if (callingUid != Process.SYSTEM_UID) {
7968            try {
7969                String pkg =
7970                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7971                int uid = mContext.getPackageManager().getPackageUid(pkg,
7972                        Binder.getCallingUserHandle().getIdentifier());
7973                if (uid != callingUid) {
7974                    throw new SecurityException("Invalid uid, expected " + uid);
7975                }
7976            } catch (NameNotFoundException e) {
7977                Log.d(TAG, "stopLockTaskMode " + e);
7978                return;
7979            }
7980        }
7981        long ident = Binder.clearCallingIdentity();
7982        try {
7983            Log.d(TAG, "stopLockTaskMode");
7984            // Stop lock task
7985            synchronized (this) {
7986                mStackSupervisor.setLockTaskModeLocked(null, false);
7987            }
7988        } finally {
7989            Binder.restoreCallingIdentity(ident);
7990        }
7991    }
7992
7993    @Override
7994    public void stopLockTaskModeOnCurrent() throws RemoteException {
7995        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7996        long ident = Binder.clearCallingIdentity();
7997        try {
7998            stopLockTaskMode();
7999        } finally {
8000            Binder.restoreCallingIdentity(ident);
8001        }
8002    }
8003
8004    @Override
8005    public boolean isInLockTaskMode() {
8006        synchronized (this) {
8007            return mStackSupervisor.isInLockTaskMode();
8008        }
8009    }
8010
8011    // =========================================================
8012    // CONTENT PROVIDERS
8013    // =========================================================
8014
8015    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8016        List<ProviderInfo> providers = null;
8017        try {
8018            providers = AppGlobals.getPackageManager().
8019                queryContentProviders(app.processName, app.uid,
8020                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8021        } catch (RemoteException ex) {
8022        }
8023        if (DEBUG_MU)
8024            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8025        int userId = app.userId;
8026        if (providers != null) {
8027            int N = providers.size();
8028            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8029            for (int i=0; i<N; i++) {
8030                ProviderInfo cpi =
8031                    (ProviderInfo)providers.get(i);
8032                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8033                        cpi.name, cpi.flags);
8034                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8035                    // This is a singleton provider, but a user besides the
8036                    // default user is asking to initialize a process it runs
8037                    // in...  well, no, it doesn't actually run in this process,
8038                    // it runs in the process of the default user.  Get rid of it.
8039                    providers.remove(i);
8040                    N--;
8041                    i--;
8042                    continue;
8043                }
8044
8045                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8046                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8047                if (cpr == null) {
8048                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8049                    mProviderMap.putProviderByClass(comp, cpr);
8050                }
8051                if (DEBUG_MU)
8052                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8053                app.pubProviders.put(cpi.name, cpr);
8054                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8055                    // Don't add this if it is a platform component that is marked
8056                    // to run in multiple processes, because this is actually
8057                    // part of the framework so doesn't make sense to track as a
8058                    // separate apk in the process.
8059                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8060                            mProcessStats);
8061                }
8062                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8063            }
8064        }
8065        return providers;
8066    }
8067
8068    /**
8069     * Check if {@link ProcessRecord} has a possible chance at accessing the
8070     * given {@link ProviderInfo}. Final permission checking is always done
8071     * in {@link ContentProvider}.
8072     */
8073    private final String checkContentProviderPermissionLocked(
8074            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8075        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8076        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8077        boolean checkedGrants = false;
8078        if (checkUser) {
8079            // Looking for cross-user grants before enforcing the typical cross-users permissions
8080            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8081            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8082                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8083                    return null;
8084                }
8085                checkedGrants = true;
8086            }
8087            userId = handleIncomingUser(callingPid, callingUid, userId,
8088                    false, ALLOW_NON_FULL,
8089                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8090            if (userId != tmpTargetUserId) {
8091                // When we actually went to determine the final targer user ID, this ended
8092                // up different than our initial check for the authority.  This is because
8093                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8094                // SELF.  So we need to re-check the grants again.
8095                checkedGrants = false;
8096            }
8097        }
8098        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8099                cpi.applicationInfo.uid, cpi.exported)
8100                == PackageManager.PERMISSION_GRANTED) {
8101            return null;
8102        }
8103        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8104                cpi.applicationInfo.uid, cpi.exported)
8105                == PackageManager.PERMISSION_GRANTED) {
8106            return null;
8107        }
8108
8109        PathPermission[] pps = cpi.pathPermissions;
8110        if (pps != null) {
8111            int i = pps.length;
8112            while (i > 0) {
8113                i--;
8114                PathPermission pp = pps[i];
8115                String pprperm = pp.getReadPermission();
8116                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8117                        cpi.applicationInfo.uid, cpi.exported)
8118                        == PackageManager.PERMISSION_GRANTED) {
8119                    return null;
8120                }
8121                String ppwperm = pp.getWritePermission();
8122                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8123                        cpi.applicationInfo.uid, cpi.exported)
8124                        == PackageManager.PERMISSION_GRANTED) {
8125                    return null;
8126                }
8127            }
8128        }
8129        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8130            return null;
8131        }
8132
8133        String msg;
8134        if (!cpi.exported) {
8135            msg = "Permission Denial: opening provider " + cpi.name
8136                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8137                    + ", uid=" + callingUid + ") that is not exported from uid "
8138                    + cpi.applicationInfo.uid;
8139        } else {
8140            msg = "Permission Denial: opening provider " + cpi.name
8141                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8142                    + ", uid=" + callingUid + ") requires "
8143                    + cpi.readPermission + " or " + cpi.writePermission;
8144        }
8145        Slog.w(TAG, msg);
8146        return msg;
8147    }
8148
8149    /**
8150     * Returns if the ContentProvider has granted a uri to callingUid
8151     */
8152    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8153        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8154        if (perms != null) {
8155            for (int i=perms.size()-1; i>=0; i--) {
8156                GrantUri grantUri = perms.keyAt(i);
8157                if (grantUri.sourceUserId == userId || !checkUser) {
8158                    if (matchesProvider(grantUri.uri, cpi)) {
8159                        return true;
8160                    }
8161                }
8162            }
8163        }
8164        return false;
8165    }
8166
8167    /**
8168     * Returns true if the uri authority is one of the authorities specified in the provider.
8169     */
8170    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8171        String uriAuth = uri.getAuthority();
8172        String cpiAuth = cpi.authority;
8173        if (cpiAuth.indexOf(';') == -1) {
8174            return cpiAuth.equals(uriAuth);
8175        }
8176        String[] cpiAuths = cpiAuth.split(";");
8177        int length = cpiAuths.length;
8178        for (int i = 0; i < length; i++) {
8179            if (cpiAuths[i].equals(uriAuth)) return true;
8180        }
8181        return false;
8182    }
8183
8184    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8185            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8186        if (r != null) {
8187            for (int i=0; i<r.conProviders.size(); i++) {
8188                ContentProviderConnection conn = r.conProviders.get(i);
8189                if (conn.provider == cpr) {
8190                    if (DEBUG_PROVIDER) Slog.v(TAG,
8191                            "Adding provider requested by "
8192                            + r.processName + " from process "
8193                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8194                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8195                    if (stable) {
8196                        conn.stableCount++;
8197                        conn.numStableIncs++;
8198                    } else {
8199                        conn.unstableCount++;
8200                        conn.numUnstableIncs++;
8201                    }
8202                    return conn;
8203                }
8204            }
8205            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8206            if (stable) {
8207                conn.stableCount = 1;
8208                conn.numStableIncs = 1;
8209            } else {
8210                conn.unstableCount = 1;
8211                conn.numUnstableIncs = 1;
8212            }
8213            cpr.connections.add(conn);
8214            r.conProviders.add(conn);
8215            return conn;
8216        }
8217        cpr.addExternalProcessHandleLocked(externalProcessToken);
8218        return null;
8219    }
8220
8221    boolean decProviderCountLocked(ContentProviderConnection conn,
8222            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8223        if (conn != null) {
8224            cpr = conn.provider;
8225            if (DEBUG_PROVIDER) Slog.v(TAG,
8226                    "Removing provider requested by "
8227                    + conn.client.processName + " from process "
8228                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8229                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8230            if (stable) {
8231                conn.stableCount--;
8232            } else {
8233                conn.unstableCount--;
8234            }
8235            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8236                cpr.connections.remove(conn);
8237                conn.client.conProviders.remove(conn);
8238                return true;
8239            }
8240            return false;
8241        }
8242        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8243        return false;
8244    }
8245
8246    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8247            String name, IBinder token, boolean stable, int userId) {
8248        ContentProviderRecord cpr;
8249        ContentProviderConnection conn = null;
8250        ProviderInfo cpi = null;
8251
8252        synchronized(this) {
8253            ProcessRecord r = null;
8254            if (caller != null) {
8255                r = getRecordForAppLocked(caller);
8256                if (r == null) {
8257                    throw new SecurityException(
8258                            "Unable to find app for caller " + caller
8259                          + " (pid=" + Binder.getCallingPid()
8260                          + ") when getting content provider " + name);
8261                }
8262            }
8263
8264            boolean checkCrossUser = true;
8265
8266            // First check if this content provider has been published...
8267            cpr = mProviderMap.getProviderByName(name, userId);
8268            // If that didn't work, check if it exists for user 0 and then
8269            // verify that it's a singleton provider before using it.
8270            if (cpr == null && userId != UserHandle.USER_OWNER) {
8271                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8272                if (cpr != null) {
8273                    cpi = cpr.info;
8274                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8275                            cpi.name, cpi.flags)
8276                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8277                        userId = UserHandle.USER_OWNER;
8278                        checkCrossUser = false;
8279                    } else {
8280                        cpr = null;
8281                        cpi = null;
8282                    }
8283                }
8284            }
8285
8286            boolean providerRunning = cpr != null;
8287            if (providerRunning) {
8288                cpi = cpr.info;
8289                String msg;
8290                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8291                        != null) {
8292                    throw new SecurityException(msg);
8293                }
8294
8295                if (r != null && cpr.canRunHere(r)) {
8296                    // This provider has been published or is in the process
8297                    // of being published...  but it is also allowed to run
8298                    // in the caller's process, so don't make a connection
8299                    // and just let the caller instantiate its own instance.
8300                    ContentProviderHolder holder = cpr.newHolder(null);
8301                    // don't give caller the provider object, it needs
8302                    // to make its own.
8303                    holder.provider = null;
8304                    return holder;
8305                }
8306
8307                final long origId = Binder.clearCallingIdentity();
8308
8309                // In this case the provider instance already exists, so we can
8310                // return it right away.
8311                conn = incProviderCountLocked(r, cpr, token, stable);
8312                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8313                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8314                        // If this is a perceptible app accessing the provider,
8315                        // make sure to count it as being accessed and thus
8316                        // back up on the LRU list.  This is good because
8317                        // content providers are often expensive to start.
8318                        updateLruProcessLocked(cpr.proc, false, null);
8319                    }
8320                }
8321
8322                if (cpr.proc != null) {
8323                    if (false) {
8324                        if (cpr.name.flattenToShortString().equals(
8325                                "com.android.providers.calendar/.CalendarProvider2")) {
8326                            Slog.v(TAG, "****************** KILLING "
8327                                + cpr.name.flattenToShortString());
8328                            Process.killProcess(cpr.proc.pid);
8329                        }
8330                    }
8331                    boolean success = updateOomAdjLocked(cpr.proc);
8332                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8333                    // NOTE: there is still a race here where a signal could be
8334                    // pending on the process even though we managed to update its
8335                    // adj level.  Not sure what to do about this, but at least
8336                    // the race is now smaller.
8337                    if (!success) {
8338                        // Uh oh...  it looks like the provider's process
8339                        // has been killed on us.  We need to wait for a new
8340                        // process to be started, and make sure its death
8341                        // doesn't kill our process.
8342                        Slog.i(TAG,
8343                                "Existing provider " + cpr.name.flattenToShortString()
8344                                + " is crashing; detaching " + r);
8345                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8346                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8347                        if (!lastRef) {
8348                            // This wasn't the last ref our process had on
8349                            // the provider...  we have now been killed, bail.
8350                            return null;
8351                        }
8352                        providerRunning = false;
8353                        conn = null;
8354                    }
8355                }
8356
8357                Binder.restoreCallingIdentity(origId);
8358            }
8359
8360            boolean singleton;
8361            if (!providerRunning) {
8362                try {
8363                    cpi = AppGlobals.getPackageManager().
8364                        resolveContentProvider(name,
8365                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8366                } catch (RemoteException ex) {
8367                }
8368                if (cpi == null) {
8369                    return null;
8370                }
8371                // If the provider is a singleton AND
8372                // (it's a call within the same user || the provider is a
8373                // privileged app)
8374                // Then allow connecting to the singleton provider
8375                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8376                        cpi.name, cpi.flags)
8377                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8378                if (singleton) {
8379                    userId = UserHandle.USER_OWNER;
8380                }
8381                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8382
8383                String msg;
8384                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8385                        != null) {
8386                    throw new SecurityException(msg);
8387                }
8388
8389                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8390                        && !cpi.processName.equals("system")) {
8391                    // If this content provider does not run in the system
8392                    // process, and the system is not yet ready to run other
8393                    // processes, then fail fast instead of hanging.
8394                    throw new IllegalArgumentException(
8395                            "Attempt to launch content provider before system ready");
8396                }
8397
8398                // Make sure that the user who owns this provider is started.  If not,
8399                // we don't want to allow it to run.
8400                if (mStartedUsers.get(userId) == null) {
8401                    Slog.w(TAG, "Unable to launch app "
8402                            + cpi.applicationInfo.packageName + "/"
8403                            + cpi.applicationInfo.uid + " for provider "
8404                            + name + ": user " + userId + " is stopped");
8405                    return null;
8406                }
8407
8408                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8409                cpr = mProviderMap.getProviderByClass(comp, userId);
8410                final boolean firstClass = cpr == null;
8411                if (firstClass) {
8412                    try {
8413                        ApplicationInfo ai =
8414                            AppGlobals.getPackageManager().
8415                                getApplicationInfo(
8416                                        cpi.applicationInfo.packageName,
8417                                        STOCK_PM_FLAGS, userId);
8418                        if (ai == null) {
8419                            Slog.w(TAG, "No package info for content provider "
8420                                    + cpi.name);
8421                            return null;
8422                        }
8423                        ai = getAppInfoForUser(ai, userId);
8424                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8425                    } catch (RemoteException ex) {
8426                        // pm is in same process, this will never happen.
8427                    }
8428                }
8429
8430                if (r != null && cpr.canRunHere(r)) {
8431                    // If this is a multiprocess provider, then just return its
8432                    // info and allow the caller to instantiate it.  Only do
8433                    // this if the provider is the same user as the caller's
8434                    // process, or can run as root (so can be in any process).
8435                    return cpr.newHolder(null);
8436                }
8437
8438                if (DEBUG_PROVIDER) {
8439                    RuntimeException e = new RuntimeException("here");
8440                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8441                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8442                }
8443
8444                // This is single process, and our app is now connecting to it.
8445                // See if we are already in the process of launching this
8446                // provider.
8447                final int N = mLaunchingProviders.size();
8448                int i;
8449                for (i=0; i<N; i++) {
8450                    if (mLaunchingProviders.get(i) == cpr) {
8451                        break;
8452                    }
8453                }
8454
8455                // If the provider is not already being launched, then get it
8456                // started.
8457                if (i >= N) {
8458                    final long origId = Binder.clearCallingIdentity();
8459
8460                    try {
8461                        // Content provider is now in use, its package can't be stopped.
8462                        try {
8463                            AppGlobals.getPackageManager().setPackageStoppedState(
8464                                    cpr.appInfo.packageName, false, userId);
8465                        } catch (RemoteException e) {
8466                        } catch (IllegalArgumentException e) {
8467                            Slog.w(TAG, "Failed trying to unstop package "
8468                                    + cpr.appInfo.packageName + ": " + e);
8469                        }
8470
8471                        // Use existing process if already started
8472                        ProcessRecord proc = getProcessRecordLocked(
8473                                cpi.processName, cpr.appInfo.uid, false);
8474                        if (proc != null && proc.thread != null) {
8475                            if (DEBUG_PROVIDER) {
8476                                Slog.d(TAG, "Installing in existing process " + proc);
8477                            }
8478                            proc.pubProviders.put(cpi.name, cpr);
8479                            try {
8480                                proc.thread.scheduleInstallProvider(cpi);
8481                            } catch (RemoteException e) {
8482                            }
8483                        } else {
8484                            proc = startProcessLocked(cpi.processName,
8485                                    cpr.appInfo, false, 0, "content provider",
8486                                    new ComponentName(cpi.applicationInfo.packageName,
8487                                            cpi.name), false, false, false);
8488                            if (proc == null) {
8489                                Slog.w(TAG, "Unable to launch app "
8490                                        + cpi.applicationInfo.packageName + "/"
8491                                        + cpi.applicationInfo.uid + " for provider "
8492                                        + name + ": process is bad");
8493                                return null;
8494                            }
8495                        }
8496                        cpr.launchingApp = proc;
8497                        mLaunchingProviders.add(cpr);
8498                    } finally {
8499                        Binder.restoreCallingIdentity(origId);
8500                    }
8501                }
8502
8503                // Make sure the provider is published (the same provider class
8504                // may be published under multiple names).
8505                if (firstClass) {
8506                    mProviderMap.putProviderByClass(comp, cpr);
8507                }
8508
8509                mProviderMap.putProviderByName(name, cpr);
8510                conn = incProviderCountLocked(r, cpr, token, stable);
8511                if (conn != null) {
8512                    conn.waiting = true;
8513                }
8514            }
8515        }
8516
8517        // Wait for the provider to be published...
8518        synchronized (cpr) {
8519            while (cpr.provider == null) {
8520                if (cpr.launchingApp == null) {
8521                    Slog.w(TAG, "Unable to launch app "
8522                            + cpi.applicationInfo.packageName + "/"
8523                            + cpi.applicationInfo.uid + " for provider "
8524                            + name + ": launching app became null");
8525                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8526                            UserHandle.getUserId(cpi.applicationInfo.uid),
8527                            cpi.applicationInfo.packageName,
8528                            cpi.applicationInfo.uid, name);
8529                    return null;
8530                }
8531                try {
8532                    if (DEBUG_MU) {
8533                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8534                                + cpr.launchingApp);
8535                    }
8536                    if (conn != null) {
8537                        conn.waiting = true;
8538                    }
8539                    cpr.wait();
8540                } catch (InterruptedException ex) {
8541                } finally {
8542                    if (conn != null) {
8543                        conn.waiting = false;
8544                    }
8545                }
8546            }
8547        }
8548        return cpr != null ? cpr.newHolder(conn) : null;
8549    }
8550
8551    @Override
8552    public final ContentProviderHolder getContentProvider(
8553            IApplicationThread caller, String name, int userId, boolean stable) {
8554        enforceNotIsolatedCaller("getContentProvider");
8555        if (caller == null) {
8556            String msg = "null IApplicationThread when getting content provider "
8557                    + name;
8558            Slog.w(TAG, msg);
8559            throw new SecurityException(msg);
8560        }
8561        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8562        // with cross-user grant.
8563        return getContentProviderImpl(caller, name, null, stable, userId);
8564    }
8565
8566    public ContentProviderHolder getContentProviderExternal(
8567            String name, int userId, IBinder token) {
8568        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8569            "Do not have permission in call getContentProviderExternal()");
8570        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8571                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8572        return getContentProviderExternalUnchecked(name, token, userId);
8573    }
8574
8575    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8576            IBinder token, int userId) {
8577        return getContentProviderImpl(null, name, token, true, userId);
8578    }
8579
8580    /**
8581     * Drop a content provider from a ProcessRecord's bookkeeping
8582     */
8583    public void removeContentProvider(IBinder connection, boolean stable) {
8584        enforceNotIsolatedCaller("removeContentProvider");
8585        long ident = Binder.clearCallingIdentity();
8586        try {
8587            synchronized (this) {
8588                ContentProviderConnection conn;
8589                try {
8590                    conn = (ContentProviderConnection)connection;
8591                } catch (ClassCastException e) {
8592                    String msg ="removeContentProvider: " + connection
8593                            + " not a ContentProviderConnection";
8594                    Slog.w(TAG, msg);
8595                    throw new IllegalArgumentException(msg);
8596                }
8597                if (conn == null) {
8598                    throw new NullPointerException("connection is null");
8599                }
8600                if (decProviderCountLocked(conn, null, null, stable)) {
8601                    updateOomAdjLocked();
8602                }
8603            }
8604        } finally {
8605            Binder.restoreCallingIdentity(ident);
8606        }
8607    }
8608
8609    public void removeContentProviderExternal(String name, IBinder token) {
8610        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8611            "Do not have permission in call removeContentProviderExternal()");
8612        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8613    }
8614
8615    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8616        synchronized (this) {
8617            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8618            if(cpr == null) {
8619                //remove from mProvidersByClass
8620                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8621                return;
8622            }
8623
8624            //update content provider record entry info
8625            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8626            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8627            if (localCpr.hasExternalProcessHandles()) {
8628                if (localCpr.removeExternalProcessHandleLocked(token)) {
8629                    updateOomAdjLocked();
8630                } else {
8631                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8632                            + " with no external reference for token: "
8633                            + token + ".");
8634                }
8635            } else {
8636                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8637                        + " with no external references.");
8638            }
8639        }
8640    }
8641
8642    public final void publishContentProviders(IApplicationThread caller,
8643            List<ContentProviderHolder> providers) {
8644        if (providers == null) {
8645            return;
8646        }
8647
8648        enforceNotIsolatedCaller("publishContentProviders");
8649        synchronized (this) {
8650            final ProcessRecord r = getRecordForAppLocked(caller);
8651            if (DEBUG_MU)
8652                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8653            if (r == null) {
8654                throw new SecurityException(
8655                        "Unable to find app for caller " + caller
8656                      + " (pid=" + Binder.getCallingPid()
8657                      + ") when publishing content providers");
8658            }
8659
8660            final long origId = Binder.clearCallingIdentity();
8661
8662            final int N = providers.size();
8663            for (int i=0; i<N; i++) {
8664                ContentProviderHolder src = providers.get(i);
8665                if (src == null || src.info == null || src.provider == null) {
8666                    continue;
8667                }
8668                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8669                if (DEBUG_MU)
8670                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8671                if (dst != null) {
8672                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8673                    mProviderMap.putProviderByClass(comp, dst);
8674                    String names[] = dst.info.authority.split(";");
8675                    for (int j = 0; j < names.length; j++) {
8676                        mProviderMap.putProviderByName(names[j], dst);
8677                    }
8678
8679                    int NL = mLaunchingProviders.size();
8680                    int j;
8681                    for (j=0; j<NL; j++) {
8682                        if (mLaunchingProviders.get(j) == dst) {
8683                            mLaunchingProviders.remove(j);
8684                            j--;
8685                            NL--;
8686                        }
8687                    }
8688                    synchronized (dst) {
8689                        dst.provider = src.provider;
8690                        dst.proc = r;
8691                        dst.notifyAll();
8692                    }
8693                    updateOomAdjLocked(r);
8694                }
8695            }
8696
8697            Binder.restoreCallingIdentity(origId);
8698        }
8699    }
8700
8701    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8702        ContentProviderConnection conn;
8703        try {
8704            conn = (ContentProviderConnection)connection;
8705        } catch (ClassCastException e) {
8706            String msg ="refContentProvider: " + connection
8707                    + " not a ContentProviderConnection";
8708            Slog.w(TAG, msg);
8709            throw new IllegalArgumentException(msg);
8710        }
8711        if (conn == null) {
8712            throw new NullPointerException("connection is null");
8713        }
8714
8715        synchronized (this) {
8716            if (stable > 0) {
8717                conn.numStableIncs += stable;
8718            }
8719            stable = conn.stableCount + stable;
8720            if (stable < 0) {
8721                throw new IllegalStateException("stableCount < 0: " + stable);
8722            }
8723
8724            if (unstable > 0) {
8725                conn.numUnstableIncs += unstable;
8726            }
8727            unstable = conn.unstableCount + unstable;
8728            if (unstable < 0) {
8729                throw new IllegalStateException("unstableCount < 0: " + unstable);
8730            }
8731
8732            if ((stable+unstable) <= 0) {
8733                throw new IllegalStateException("ref counts can't go to zero here: stable="
8734                        + stable + " unstable=" + unstable);
8735            }
8736            conn.stableCount = stable;
8737            conn.unstableCount = unstable;
8738            return !conn.dead;
8739        }
8740    }
8741
8742    public void unstableProviderDied(IBinder connection) {
8743        ContentProviderConnection conn;
8744        try {
8745            conn = (ContentProviderConnection)connection;
8746        } catch (ClassCastException e) {
8747            String msg ="refContentProvider: " + connection
8748                    + " not a ContentProviderConnection";
8749            Slog.w(TAG, msg);
8750            throw new IllegalArgumentException(msg);
8751        }
8752        if (conn == null) {
8753            throw new NullPointerException("connection is null");
8754        }
8755
8756        // Safely retrieve the content provider associated with the connection.
8757        IContentProvider provider;
8758        synchronized (this) {
8759            provider = conn.provider.provider;
8760        }
8761
8762        if (provider == null) {
8763            // Um, yeah, we're way ahead of you.
8764            return;
8765        }
8766
8767        // Make sure the caller is being honest with us.
8768        if (provider.asBinder().pingBinder()) {
8769            // Er, no, still looks good to us.
8770            synchronized (this) {
8771                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8772                        + " says " + conn + " died, but we don't agree");
8773                return;
8774            }
8775        }
8776
8777        // Well look at that!  It's dead!
8778        synchronized (this) {
8779            if (conn.provider.provider != provider) {
8780                // But something changed...  good enough.
8781                return;
8782            }
8783
8784            ProcessRecord proc = conn.provider.proc;
8785            if (proc == null || proc.thread == null) {
8786                // Seems like the process is already cleaned up.
8787                return;
8788            }
8789
8790            // As far as we're concerned, this is just like receiving a
8791            // death notification...  just a bit prematurely.
8792            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8793                    + ") early provider death");
8794            final long ident = Binder.clearCallingIdentity();
8795            try {
8796                appDiedLocked(proc, proc.pid, proc.thread);
8797            } finally {
8798                Binder.restoreCallingIdentity(ident);
8799            }
8800        }
8801    }
8802
8803    @Override
8804    public void appNotRespondingViaProvider(IBinder connection) {
8805        enforceCallingPermission(
8806                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8807
8808        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8809        if (conn == null) {
8810            Slog.w(TAG, "ContentProviderConnection is null");
8811            return;
8812        }
8813
8814        final ProcessRecord host = conn.provider.proc;
8815        if (host == null) {
8816            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8817            return;
8818        }
8819
8820        final long token = Binder.clearCallingIdentity();
8821        try {
8822            appNotResponding(host, null, null, false, "ContentProvider not responding");
8823        } finally {
8824            Binder.restoreCallingIdentity(token);
8825        }
8826    }
8827
8828    public final void installSystemProviders() {
8829        List<ProviderInfo> providers;
8830        synchronized (this) {
8831            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8832            providers = generateApplicationProvidersLocked(app);
8833            if (providers != null) {
8834                for (int i=providers.size()-1; i>=0; i--) {
8835                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8836                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8837                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8838                                + ": not system .apk");
8839                        providers.remove(i);
8840                    }
8841                }
8842            }
8843        }
8844        if (providers != null) {
8845            mSystemThread.installSystemProviders(providers);
8846        }
8847
8848        mCoreSettingsObserver = new CoreSettingsObserver(this);
8849
8850        //mUsageStatsService.monitorPackages();
8851    }
8852
8853    /**
8854     * Allows app to retrieve the MIME type of a URI without having permission
8855     * to access its content provider.
8856     *
8857     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8858     *
8859     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8860     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8861     */
8862    public String getProviderMimeType(Uri uri, int userId) {
8863        enforceNotIsolatedCaller("getProviderMimeType");
8864        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8865                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8866        final String name = uri.getAuthority();
8867        final long ident = Binder.clearCallingIdentity();
8868        ContentProviderHolder holder = null;
8869
8870        try {
8871            holder = getContentProviderExternalUnchecked(name, null, userId);
8872            if (holder != null) {
8873                return holder.provider.getType(uri);
8874            }
8875        } catch (RemoteException e) {
8876            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8877            return null;
8878        } finally {
8879            if (holder != null) {
8880                removeContentProviderExternalUnchecked(name, null, userId);
8881            }
8882            Binder.restoreCallingIdentity(ident);
8883        }
8884
8885        return null;
8886    }
8887
8888    // =========================================================
8889    // GLOBAL MANAGEMENT
8890    // =========================================================
8891
8892    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8893            boolean isolated) {
8894        String proc = customProcess != null ? customProcess : info.processName;
8895        BatteryStatsImpl.Uid.Proc ps = null;
8896        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8897        int uid = info.uid;
8898        if (isolated) {
8899            int userId = UserHandle.getUserId(uid);
8900            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8901            while (true) {
8902                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8903                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8904                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8905                }
8906                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8907                mNextIsolatedProcessUid++;
8908                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8909                    // No process for this uid, use it.
8910                    break;
8911                }
8912                stepsLeft--;
8913                if (stepsLeft <= 0) {
8914                    return null;
8915                }
8916            }
8917        }
8918        return new ProcessRecord(stats, info, proc, uid);
8919    }
8920
8921    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8922            String abiOverride) {
8923        ProcessRecord app;
8924        if (!isolated) {
8925            app = getProcessRecordLocked(info.processName, info.uid, true);
8926        } else {
8927            app = null;
8928        }
8929
8930        if (app == null) {
8931            app = newProcessRecordLocked(info, null, isolated);
8932            mProcessNames.put(info.processName, app.uid, app);
8933            if (isolated) {
8934                mIsolatedProcesses.put(app.uid, app);
8935            }
8936            updateLruProcessLocked(app, false, null);
8937            updateOomAdjLocked();
8938        }
8939
8940        // This package really, really can not be stopped.
8941        try {
8942            AppGlobals.getPackageManager().setPackageStoppedState(
8943                    info.packageName, false, UserHandle.getUserId(app.uid));
8944        } catch (RemoteException e) {
8945        } catch (IllegalArgumentException e) {
8946            Slog.w(TAG, "Failed trying to unstop package "
8947                    + info.packageName + ": " + e);
8948        }
8949
8950        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8951                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8952            app.persistent = true;
8953            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8954        }
8955        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8956            mPersistentStartingProcesses.add(app);
8957            startProcessLocked(app, "added application", app.processName,
8958                    abiOverride);
8959        }
8960
8961        return app;
8962    }
8963
8964    public void unhandledBack() {
8965        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8966                "unhandledBack()");
8967
8968        synchronized(this) {
8969            final long origId = Binder.clearCallingIdentity();
8970            try {
8971                getFocusedStack().unhandledBackLocked();
8972            } finally {
8973                Binder.restoreCallingIdentity(origId);
8974            }
8975        }
8976    }
8977
8978    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8979        enforceNotIsolatedCaller("openContentUri");
8980        final int userId = UserHandle.getCallingUserId();
8981        String name = uri.getAuthority();
8982        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8983        ParcelFileDescriptor pfd = null;
8984        if (cph != null) {
8985            // We record the binder invoker's uid in thread-local storage before
8986            // going to the content provider to open the file.  Later, in the code
8987            // that handles all permissions checks, we look for this uid and use
8988            // that rather than the Activity Manager's own uid.  The effect is that
8989            // we do the check against the caller's permissions even though it looks
8990            // to the content provider like the Activity Manager itself is making
8991            // the request.
8992            sCallerIdentity.set(new Identity(
8993                    Binder.getCallingPid(), Binder.getCallingUid()));
8994            try {
8995                pfd = cph.provider.openFile(null, uri, "r", null);
8996            } catch (FileNotFoundException e) {
8997                // do nothing; pfd will be returned null
8998            } finally {
8999                // Ensure that whatever happens, we clean up the identity state
9000                sCallerIdentity.remove();
9001            }
9002
9003            // We've got the fd now, so we're done with the provider.
9004            removeContentProviderExternalUnchecked(name, null, userId);
9005        } else {
9006            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9007        }
9008        return pfd;
9009    }
9010
9011    // Actually is sleeping or shutting down or whatever else in the future
9012    // is an inactive state.
9013    public boolean isSleepingOrShuttingDown() {
9014        return mSleeping || mShuttingDown;
9015    }
9016
9017    public boolean isSleeping() {
9018        return mSleeping;
9019    }
9020
9021    void goingToSleep() {
9022        synchronized(this) {
9023            mWentToSleep = true;
9024            updateEventDispatchingLocked();
9025            goToSleepIfNeededLocked();
9026        }
9027    }
9028
9029    void finishRunningVoiceLocked() {
9030        if (mRunningVoice) {
9031            mRunningVoice = false;
9032            goToSleepIfNeededLocked();
9033        }
9034    }
9035
9036    void goToSleepIfNeededLocked() {
9037        if (mWentToSleep && !mRunningVoice) {
9038            if (!mSleeping) {
9039                mSleeping = true;
9040                mStackSupervisor.goingToSleepLocked();
9041
9042                // Initialize the wake times of all processes.
9043                checkExcessivePowerUsageLocked(false);
9044                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9045                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9046                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9047            }
9048        }
9049    }
9050
9051    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9052        mTaskPersister.notify(task, flush);
9053    }
9054
9055    @Override
9056    public boolean shutdown(int timeout) {
9057        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9058                != PackageManager.PERMISSION_GRANTED) {
9059            throw new SecurityException("Requires permission "
9060                    + android.Manifest.permission.SHUTDOWN);
9061        }
9062
9063        boolean timedout = false;
9064
9065        synchronized(this) {
9066            mShuttingDown = true;
9067            updateEventDispatchingLocked();
9068            timedout = mStackSupervisor.shutdownLocked(timeout);
9069        }
9070
9071        mAppOpsService.shutdown();
9072        if (mUsageStatsService != null) {
9073            mUsageStatsService.prepareShutdown();
9074        }
9075        mBatteryStatsService.shutdown();
9076        synchronized (this) {
9077            mProcessStats.shutdownLocked();
9078        }
9079        notifyTaskPersisterLocked(null, true);
9080
9081        return timedout;
9082    }
9083
9084    public final void activitySlept(IBinder token) {
9085        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9086
9087        final long origId = Binder.clearCallingIdentity();
9088
9089        synchronized (this) {
9090            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9091            if (r != null) {
9092                mStackSupervisor.activitySleptLocked(r);
9093            }
9094        }
9095
9096        Binder.restoreCallingIdentity(origId);
9097    }
9098
9099    void logLockScreen(String msg) {
9100        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9101                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9102                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9103                mStackSupervisor.mDismissKeyguardOnNextActivity);
9104    }
9105
9106    private void comeOutOfSleepIfNeededLocked() {
9107        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9108            if (mSleeping) {
9109                mSleeping = false;
9110                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9111            }
9112        }
9113    }
9114
9115    void wakingUp() {
9116        synchronized(this) {
9117            mWentToSleep = false;
9118            updateEventDispatchingLocked();
9119            comeOutOfSleepIfNeededLocked();
9120        }
9121    }
9122
9123    void startRunningVoiceLocked() {
9124        if (!mRunningVoice) {
9125            mRunningVoice = true;
9126            comeOutOfSleepIfNeededLocked();
9127        }
9128    }
9129
9130    private void updateEventDispatchingLocked() {
9131        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9132    }
9133
9134    public void setLockScreenShown(boolean shown) {
9135        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9136                != PackageManager.PERMISSION_GRANTED) {
9137            throw new SecurityException("Requires permission "
9138                    + android.Manifest.permission.DEVICE_POWER);
9139        }
9140
9141        synchronized(this) {
9142            long ident = Binder.clearCallingIdentity();
9143            try {
9144                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9145                mLockScreenShown = shown;
9146                comeOutOfSleepIfNeededLocked();
9147            } finally {
9148                Binder.restoreCallingIdentity(ident);
9149            }
9150        }
9151    }
9152
9153    @Override
9154    public void stopAppSwitches() {
9155        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9156                != PackageManager.PERMISSION_GRANTED) {
9157            throw new SecurityException("Requires permission "
9158                    + android.Manifest.permission.STOP_APP_SWITCHES);
9159        }
9160
9161        synchronized(this) {
9162            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9163                    + APP_SWITCH_DELAY_TIME;
9164            mDidAppSwitch = false;
9165            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9166            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9167            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9168        }
9169    }
9170
9171    public void resumeAppSwitches() {
9172        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9173                != PackageManager.PERMISSION_GRANTED) {
9174            throw new SecurityException("Requires permission "
9175                    + android.Manifest.permission.STOP_APP_SWITCHES);
9176        }
9177
9178        synchronized(this) {
9179            // Note that we don't execute any pending app switches... we will
9180            // let those wait until either the timeout, or the next start
9181            // activity request.
9182            mAppSwitchesAllowedTime = 0;
9183        }
9184    }
9185
9186    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9187            String name) {
9188        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9189            return true;
9190        }
9191
9192        final int perm = checkComponentPermission(
9193                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9194                callingUid, -1, true);
9195        if (perm == PackageManager.PERMISSION_GRANTED) {
9196            return true;
9197        }
9198
9199        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9200        return false;
9201    }
9202
9203    public void setDebugApp(String packageName, boolean waitForDebugger,
9204            boolean persistent) {
9205        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9206                "setDebugApp()");
9207
9208        long ident = Binder.clearCallingIdentity();
9209        try {
9210            // Note that this is not really thread safe if there are multiple
9211            // callers into it at the same time, but that's not a situation we
9212            // care about.
9213            if (persistent) {
9214                final ContentResolver resolver = mContext.getContentResolver();
9215                Settings.Global.putString(
9216                    resolver, Settings.Global.DEBUG_APP,
9217                    packageName);
9218                Settings.Global.putInt(
9219                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9220                    waitForDebugger ? 1 : 0);
9221            }
9222
9223            synchronized (this) {
9224                if (!persistent) {
9225                    mOrigDebugApp = mDebugApp;
9226                    mOrigWaitForDebugger = mWaitForDebugger;
9227                }
9228                mDebugApp = packageName;
9229                mWaitForDebugger = waitForDebugger;
9230                mDebugTransient = !persistent;
9231                if (packageName != null) {
9232                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9233                            false, UserHandle.USER_ALL, "set debug app");
9234                }
9235            }
9236        } finally {
9237            Binder.restoreCallingIdentity(ident);
9238        }
9239    }
9240
9241    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9242        synchronized (this) {
9243            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9244            if (!isDebuggable) {
9245                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9246                    throw new SecurityException("Process not debuggable: " + app.packageName);
9247                }
9248            }
9249
9250            mOpenGlTraceApp = processName;
9251        }
9252    }
9253
9254    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9255            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9256        synchronized (this) {
9257            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9258            if (!isDebuggable) {
9259                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9260                    throw new SecurityException("Process not debuggable: " + app.packageName);
9261                }
9262            }
9263            mProfileApp = processName;
9264            mProfileFile = profileFile;
9265            if (mProfileFd != null) {
9266                try {
9267                    mProfileFd.close();
9268                } catch (IOException e) {
9269                }
9270                mProfileFd = null;
9271            }
9272            mProfileFd = profileFd;
9273            mProfileType = 0;
9274            mAutoStopProfiler = autoStopProfiler;
9275        }
9276    }
9277
9278    @Override
9279    public void setAlwaysFinish(boolean enabled) {
9280        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9281                "setAlwaysFinish()");
9282
9283        Settings.Global.putInt(
9284                mContext.getContentResolver(),
9285                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9286
9287        synchronized (this) {
9288            mAlwaysFinishActivities = enabled;
9289        }
9290    }
9291
9292    @Override
9293    public void setActivityController(IActivityController controller) {
9294        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9295                "setActivityController()");
9296        synchronized (this) {
9297            mController = controller;
9298            Watchdog.getInstance().setActivityController(controller);
9299        }
9300    }
9301
9302    @Override
9303    public void setUserIsMonkey(boolean userIsMonkey) {
9304        synchronized (this) {
9305            synchronized (mPidsSelfLocked) {
9306                final int callingPid = Binder.getCallingPid();
9307                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9308                if (precessRecord == null) {
9309                    throw new SecurityException("Unknown process: " + callingPid);
9310                }
9311                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9312                    throw new SecurityException("Only an instrumentation process "
9313                            + "with a UiAutomation can call setUserIsMonkey");
9314                }
9315            }
9316            mUserIsMonkey = userIsMonkey;
9317        }
9318    }
9319
9320    @Override
9321    public boolean isUserAMonkey() {
9322        synchronized (this) {
9323            // If there is a controller also implies the user is a monkey.
9324            return (mUserIsMonkey || mController != null);
9325        }
9326    }
9327
9328    public void requestBugReport() {
9329        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9330        SystemProperties.set("ctl.start", "bugreport");
9331    }
9332
9333    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9334        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9335    }
9336
9337    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9338        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9339            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9340        }
9341        return KEY_DISPATCHING_TIMEOUT;
9342    }
9343
9344    @Override
9345    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9346        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9347                != PackageManager.PERMISSION_GRANTED) {
9348            throw new SecurityException("Requires permission "
9349                    + android.Manifest.permission.FILTER_EVENTS);
9350        }
9351        ProcessRecord proc;
9352        long timeout;
9353        synchronized (this) {
9354            synchronized (mPidsSelfLocked) {
9355                proc = mPidsSelfLocked.get(pid);
9356            }
9357            timeout = getInputDispatchingTimeoutLocked(proc);
9358        }
9359
9360        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9361            return -1;
9362        }
9363
9364        return timeout;
9365    }
9366
9367    /**
9368     * Handle input dispatching timeouts.
9369     * Returns whether input dispatching should be aborted or not.
9370     */
9371    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9372            final ActivityRecord activity, final ActivityRecord parent,
9373            final boolean aboveSystem, String reason) {
9374        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9375                != PackageManager.PERMISSION_GRANTED) {
9376            throw new SecurityException("Requires permission "
9377                    + android.Manifest.permission.FILTER_EVENTS);
9378        }
9379
9380        final String annotation;
9381        if (reason == null) {
9382            annotation = "Input dispatching timed out";
9383        } else {
9384            annotation = "Input dispatching timed out (" + reason + ")";
9385        }
9386
9387        if (proc != null) {
9388            synchronized (this) {
9389                if (proc.debugging) {
9390                    return false;
9391                }
9392
9393                if (mDidDexOpt) {
9394                    // Give more time since we were dexopting.
9395                    mDidDexOpt = false;
9396                    return false;
9397                }
9398
9399                if (proc.instrumentationClass != null) {
9400                    Bundle info = new Bundle();
9401                    info.putString("shortMsg", "keyDispatchingTimedOut");
9402                    info.putString("longMsg", annotation);
9403                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9404                    return true;
9405                }
9406            }
9407            mHandler.post(new Runnable() {
9408                @Override
9409                public void run() {
9410                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9411                }
9412            });
9413        }
9414
9415        return true;
9416    }
9417
9418    public Bundle getAssistContextExtras(int requestType) {
9419        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9420                "getAssistContextExtras()");
9421        PendingAssistExtras pae;
9422        Bundle extras = new Bundle();
9423        synchronized (this) {
9424            ActivityRecord activity = getFocusedStack().mResumedActivity;
9425            if (activity == null) {
9426                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9427                return null;
9428            }
9429            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9430            if (activity.app == null || activity.app.thread == null) {
9431                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9432                return extras;
9433            }
9434            if (activity.app.pid == Binder.getCallingPid()) {
9435                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9436                return extras;
9437            }
9438            pae = new PendingAssistExtras(activity);
9439            try {
9440                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9441                        requestType);
9442                mPendingAssistExtras.add(pae);
9443                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9444            } catch (RemoteException e) {
9445                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9446                return extras;
9447            }
9448        }
9449        synchronized (pae) {
9450            while (!pae.haveResult) {
9451                try {
9452                    pae.wait();
9453                } catch (InterruptedException e) {
9454                }
9455            }
9456            if (pae.result != null) {
9457                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9458            }
9459        }
9460        synchronized (this) {
9461            mPendingAssistExtras.remove(pae);
9462            mHandler.removeCallbacks(pae);
9463        }
9464        return extras;
9465    }
9466
9467    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9468        PendingAssistExtras pae = (PendingAssistExtras)token;
9469        synchronized (pae) {
9470            pae.result = extras;
9471            pae.haveResult = true;
9472            pae.notifyAll();
9473        }
9474    }
9475
9476    public void registerProcessObserver(IProcessObserver observer) {
9477        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9478                "registerProcessObserver()");
9479        synchronized (this) {
9480            mProcessObservers.register(observer);
9481        }
9482    }
9483
9484    @Override
9485    public void unregisterProcessObserver(IProcessObserver observer) {
9486        synchronized (this) {
9487            mProcessObservers.unregister(observer);
9488        }
9489    }
9490
9491    @Override
9492    public boolean convertFromTranslucent(IBinder token) {
9493        final long origId = Binder.clearCallingIdentity();
9494        try {
9495            synchronized (this) {
9496                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9497                if (r == null) {
9498                    return false;
9499                }
9500                if (r.changeWindowTranslucency(true)) {
9501                    mWindowManager.setAppFullscreen(token, true);
9502                    r.task.stack.releaseMediaResources();
9503                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9504                    return true;
9505                }
9506                return false;
9507            }
9508        } finally {
9509            Binder.restoreCallingIdentity(origId);
9510        }
9511    }
9512
9513    @Override
9514    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9515        final long origId = Binder.clearCallingIdentity();
9516        try {
9517            synchronized (this) {
9518                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9519                if (r == null) {
9520                    return false;
9521                }
9522                if (r.changeWindowTranslucency(false)) {
9523                    r.task.stack.convertToTranslucent(r, options);
9524                    mWindowManager.setAppFullscreen(token, false);
9525                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9526                    return true;
9527                } else {
9528                    r.task.stack.mReturningActivityOptions = options;
9529                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9530                    return false;
9531                }
9532            }
9533        } finally {
9534            Binder.restoreCallingIdentity(origId);
9535        }
9536    }
9537
9538    @Override
9539    public boolean setMediaPlaying(IBinder token, boolean playing) {
9540        final long origId = Binder.clearCallingIdentity();
9541        try {
9542            synchronized (this) {
9543                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9544                if (r != null) {
9545                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9546                }
9547            }
9548            return false;
9549        } finally {
9550            Binder.restoreCallingIdentity(origId);
9551        }
9552    }
9553
9554    @Override
9555    public boolean isBackgroundMediaPlaying(IBinder token) {
9556        final long origId = Binder.clearCallingIdentity();
9557        try {
9558            synchronized (this) {
9559                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9560                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9561                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9562                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9563                return playing;
9564            }
9565        } finally {
9566            Binder.restoreCallingIdentity(origId);
9567        }
9568    }
9569
9570    @Override
9571    public ActivityOptions getActivityOptions(IBinder token) {
9572        final long origId = Binder.clearCallingIdentity();
9573        try {
9574            synchronized (this) {
9575                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9576                if (r != null) {
9577                    final ActivityOptions activityOptions = r.pendingOptions;
9578                    r.pendingOptions = null;
9579                    return activityOptions;
9580                }
9581                return null;
9582            }
9583        } finally {
9584            Binder.restoreCallingIdentity(origId);
9585        }
9586    }
9587
9588    @Override
9589    public void setImmersive(IBinder token, boolean immersive) {
9590        synchronized(this) {
9591            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9592            if (r == null) {
9593                throw new IllegalArgumentException();
9594            }
9595            r.immersive = immersive;
9596
9597            // update associated state if we're frontmost
9598            if (r == mFocusedActivity) {
9599                if (DEBUG_IMMERSIVE) {
9600                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9601                }
9602                applyUpdateLockStateLocked(r);
9603            }
9604        }
9605    }
9606
9607    @Override
9608    public boolean isImmersive(IBinder token) {
9609        synchronized (this) {
9610            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9611            if (r == null) {
9612                throw new IllegalArgumentException();
9613            }
9614            return r.immersive;
9615        }
9616    }
9617
9618    public boolean isTopActivityImmersive() {
9619        enforceNotIsolatedCaller("startActivity");
9620        synchronized (this) {
9621            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9622            return (r != null) ? r.immersive : false;
9623        }
9624    }
9625
9626    @Override
9627    public boolean isTopOfTask(IBinder token) {
9628        synchronized (this) {
9629            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9630            if (r == null) {
9631                throw new IllegalArgumentException();
9632            }
9633            return r.task.getTopActivity() == r;
9634        }
9635    }
9636
9637    public final void enterSafeMode() {
9638        synchronized(this) {
9639            // It only makes sense to do this before the system is ready
9640            // and started launching other packages.
9641            if (!mSystemReady) {
9642                try {
9643                    AppGlobals.getPackageManager().enterSafeMode();
9644                } catch (RemoteException e) {
9645                }
9646            }
9647
9648            mSafeMode = true;
9649        }
9650    }
9651
9652    public final void showSafeModeOverlay() {
9653        View v = LayoutInflater.from(mContext).inflate(
9654                com.android.internal.R.layout.safe_mode, null);
9655        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9656        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9657        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9658        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9659        lp.gravity = Gravity.BOTTOM | Gravity.START;
9660        lp.format = v.getBackground().getOpacity();
9661        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9662                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9663        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9664        ((WindowManager)mContext.getSystemService(
9665                Context.WINDOW_SERVICE)).addView(v, lp);
9666    }
9667
9668    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9669        if (!(sender instanceof PendingIntentRecord)) {
9670            return;
9671        }
9672        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9673        synchronized (stats) {
9674            if (mBatteryStatsService.isOnBattery()) {
9675                mBatteryStatsService.enforceCallingPermission();
9676                PendingIntentRecord rec = (PendingIntentRecord)sender;
9677                int MY_UID = Binder.getCallingUid();
9678                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9679                BatteryStatsImpl.Uid.Pkg pkg =
9680                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9681                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9682                pkg.incWakeupsLocked();
9683            }
9684        }
9685    }
9686
9687    public boolean killPids(int[] pids, String pReason, boolean secure) {
9688        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9689            throw new SecurityException("killPids only available to the system");
9690        }
9691        String reason = (pReason == null) ? "Unknown" : pReason;
9692        // XXX Note: don't acquire main activity lock here, because the window
9693        // manager calls in with its locks held.
9694
9695        boolean killed = false;
9696        synchronized (mPidsSelfLocked) {
9697            int[] types = new int[pids.length];
9698            int worstType = 0;
9699            for (int i=0; i<pids.length; i++) {
9700                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9701                if (proc != null) {
9702                    int type = proc.setAdj;
9703                    types[i] = type;
9704                    if (type > worstType) {
9705                        worstType = type;
9706                    }
9707                }
9708            }
9709
9710            // If the worst oom_adj is somewhere in the cached proc LRU range,
9711            // then constrain it so we will kill all cached procs.
9712            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9713                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9714                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9715            }
9716
9717            // If this is not a secure call, don't let it kill processes that
9718            // are important.
9719            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9720                worstType = ProcessList.SERVICE_ADJ;
9721            }
9722
9723            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9724            for (int i=0; i<pids.length; i++) {
9725                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9726                if (proc == null) {
9727                    continue;
9728                }
9729                int adj = proc.setAdj;
9730                if (adj >= worstType && !proc.killedByAm) {
9731                    killUnneededProcessLocked(proc, reason);
9732                    killed = true;
9733                }
9734            }
9735        }
9736        return killed;
9737    }
9738
9739    @Override
9740    public void killUid(int uid, String reason) {
9741        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9742            throw new SecurityException("killUid only available to the system");
9743        }
9744        synchronized (this) {
9745            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9746                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9747                    reason != null ? reason : "kill uid");
9748        }
9749    }
9750
9751    @Override
9752    public boolean killProcessesBelowForeground(String reason) {
9753        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9754            throw new SecurityException("killProcessesBelowForeground() only available to system");
9755        }
9756
9757        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9758    }
9759
9760    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9761        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9762            throw new SecurityException("killProcessesBelowAdj() only available to system");
9763        }
9764
9765        boolean killed = false;
9766        synchronized (mPidsSelfLocked) {
9767            final int size = mPidsSelfLocked.size();
9768            for (int i = 0; i < size; i++) {
9769                final int pid = mPidsSelfLocked.keyAt(i);
9770                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9771                if (proc == null) continue;
9772
9773                final int adj = proc.setAdj;
9774                if (adj > belowAdj && !proc.killedByAm) {
9775                    killUnneededProcessLocked(proc, reason);
9776                    killed = true;
9777                }
9778            }
9779        }
9780        return killed;
9781    }
9782
9783    @Override
9784    public void hang(final IBinder who, boolean allowRestart) {
9785        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9786                != PackageManager.PERMISSION_GRANTED) {
9787            throw new SecurityException("Requires permission "
9788                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9789        }
9790
9791        final IBinder.DeathRecipient death = new DeathRecipient() {
9792            @Override
9793            public void binderDied() {
9794                synchronized (this) {
9795                    notifyAll();
9796                }
9797            }
9798        };
9799
9800        try {
9801            who.linkToDeath(death, 0);
9802        } catch (RemoteException e) {
9803            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9804            return;
9805        }
9806
9807        synchronized (this) {
9808            Watchdog.getInstance().setAllowRestart(allowRestart);
9809            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9810            synchronized (death) {
9811                while (who.isBinderAlive()) {
9812                    try {
9813                        death.wait();
9814                    } catch (InterruptedException e) {
9815                    }
9816                }
9817            }
9818            Watchdog.getInstance().setAllowRestart(true);
9819        }
9820    }
9821
9822    @Override
9823    public void restart() {
9824        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9825                != PackageManager.PERMISSION_GRANTED) {
9826            throw new SecurityException("Requires permission "
9827                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9828        }
9829
9830        Log.i(TAG, "Sending shutdown broadcast...");
9831
9832        BroadcastReceiver br = new BroadcastReceiver() {
9833            @Override public void onReceive(Context context, Intent intent) {
9834                // Now the broadcast is done, finish up the low-level shutdown.
9835                Log.i(TAG, "Shutting down activity manager...");
9836                shutdown(10000);
9837                Log.i(TAG, "Shutdown complete, restarting!");
9838                Process.killProcess(Process.myPid());
9839                System.exit(10);
9840            }
9841        };
9842
9843        // First send the high-level shut down broadcast.
9844        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9845        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9846        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9847        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9848        mContext.sendOrderedBroadcastAsUser(intent,
9849                UserHandle.ALL, null, br, mHandler, 0, null, null);
9850        */
9851        br.onReceive(mContext, intent);
9852    }
9853
9854    private long getLowRamTimeSinceIdle(long now) {
9855        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9856    }
9857
9858    @Override
9859    public void performIdleMaintenance() {
9860        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9861                != PackageManager.PERMISSION_GRANTED) {
9862            throw new SecurityException("Requires permission "
9863                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9864        }
9865
9866        synchronized (this) {
9867            final long now = SystemClock.uptimeMillis();
9868            final long timeSinceLastIdle = now - mLastIdleTime;
9869            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9870            mLastIdleTime = now;
9871            mLowRamTimeSinceLastIdle = 0;
9872            if (mLowRamStartTime != 0) {
9873                mLowRamStartTime = now;
9874            }
9875
9876            StringBuilder sb = new StringBuilder(128);
9877            sb.append("Idle maintenance over ");
9878            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9879            sb.append(" low RAM for ");
9880            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9881            Slog.i(TAG, sb.toString());
9882
9883            // If at least 1/3 of our time since the last idle period has been spent
9884            // with RAM low, then we want to kill processes.
9885            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9886
9887            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9888                ProcessRecord proc = mLruProcesses.get(i);
9889                if (proc.notCachedSinceIdle) {
9890                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9891                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9892                        if (doKilling && proc.initialIdlePss != 0
9893                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9894                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9895                                    + " from " + proc.initialIdlePss + ")");
9896                        }
9897                    }
9898                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9899                    proc.notCachedSinceIdle = true;
9900                    proc.initialIdlePss = 0;
9901                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9902                            isSleeping(), now);
9903                }
9904            }
9905
9906            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9907            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9908        }
9909    }
9910
9911    private void retrieveSettings() {
9912        final ContentResolver resolver = mContext.getContentResolver();
9913        String debugApp = Settings.Global.getString(
9914            resolver, Settings.Global.DEBUG_APP);
9915        boolean waitForDebugger = Settings.Global.getInt(
9916            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9917        boolean alwaysFinishActivities = Settings.Global.getInt(
9918            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9919        boolean forceRtl = Settings.Global.getInt(
9920                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9921        // Transfer any global setting for forcing RTL layout, into a System Property
9922        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9923
9924        Configuration configuration = new Configuration();
9925        Settings.System.getConfiguration(resolver, configuration);
9926        if (forceRtl) {
9927            // This will take care of setting the correct layout direction flags
9928            configuration.setLayoutDirection(configuration.locale);
9929        }
9930
9931        synchronized (this) {
9932            mDebugApp = mOrigDebugApp = debugApp;
9933            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9934            mAlwaysFinishActivities = alwaysFinishActivities;
9935            // This happens before any activities are started, so we can
9936            // change mConfiguration in-place.
9937            updateConfigurationLocked(configuration, null, false, true);
9938            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9939        }
9940    }
9941
9942    public boolean testIsSystemReady() {
9943        // no need to synchronize(this) just to read & return the value
9944        return mSystemReady;
9945    }
9946
9947    private static File getCalledPreBootReceiversFile() {
9948        File dataDir = Environment.getDataDirectory();
9949        File systemDir = new File(dataDir, "system");
9950        File fname = new File(systemDir, "called_pre_boots.dat");
9951        return fname;
9952    }
9953
9954    static final int LAST_DONE_VERSION = 10000;
9955
9956    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9957        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9958        File file = getCalledPreBootReceiversFile();
9959        FileInputStream fis = null;
9960        try {
9961            fis = new FileInputStream(file);
9962            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9963            int fvers = dis.readInt();
9964            if (fvers == LAST_DONE_VERSION) {
9965                String vers = dis.readUTF();
9966                String codename = dis.readUTF();
9967                String build = dis.readUTF();
9968                if (android.os.Build.VERSION.RELEASE.equals(vers)
9969                        && android.os.Build.VERSION.CODENAME.equals(codename)
9970                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9971                    int num = dis.readInt();
9972                    while (num > 0) {
9973                        num--;
9974                        String pkg = dis.readUTF();
9975                        String cls = dis.readUTF();
9976                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9977                    }
9978                }
9979            }
9980        } catch (FileNotFoundException e) {
9981        } catch (IOException e) {
9982            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9983        } finally {
9984            if (fis != null) {
9985                try {
9986                    fis.close();
9987                } catch (IOException e) {
9988                }
9989            }
9990        }
9991        return lastDoneReceivers;
9992    }
9993
9994    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9995        File file = getCalledPreBootReceiversFile();
9996        FileOutputStream fos = null;
9997        DataOutputStream dos = null;
9998        try {
9999            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
10000            fos = new FileOutputStream(file);
10001            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10002            dos.writeInt(LAST_DONE_VERSION);
10003            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10004            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10005            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10006            dos.writeInt(list.size());
10007            for (int i=0; i<list.size(); i++) {
10008                dos.writeUTF(list.get(i).getPackageName());
10009                dos.writeUTF(list.get(i).getClassName());
10010            }
10011        } catch (IOException e) {
10012            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10013            file.delete();
10014        } finally {
10015            FileUtils.sync(fos);
10016            if (dos != null) {
10017                try {
10018                    dos.close();
10019                } catch (IOException e) {
10020                    // TODO Auto-generated catch block
10021                    e.printStackTrace();
10022                }
10023            }
10024        }
10025    }
10026
10027    public void systemReady(final Runnable goingCallback) {
10028        synchronized(this) {
10029            if (mSystemReady) {
10030                if (goingCallback != null) goingCallback.run();
10031                return;
10032            }
10033
10034            // Make sure we have the current profile info, since it is needed for
10035            // security checks.
10036            updateCurrentProfileIdsLocked();
10037
10038            if (mRecentTasks == null) {
10039                mRecentTasks = mTaskPersister.restoreTasksLocked();
10040                if (!mRecentTasks.isEmpty()) {
10041                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10042                }
10043                mTaskPersister.startPersisting();
10044            }
10045
10046            // Check to see if there are any update receivers to run.
10047            if (!mDidUpdate) {
10048                if (mWaitingUpdate) {
10049                    return;
10050                }
10051                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10052                List<ResolveInfo> ris = null;
10053                try {
10054                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
10055                            intent, null, 0, 0);
10056                } catch (RemoteException e) {
10057                }
10058                if (ris != null) {
10059                    for (int i=ris.size()-1; i>=0; i--) {
10060                        if ((ris.get(i).activityInfo.applicationInfo.flags
10061                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
10062                            ris.remove(i);
10063                        }
10064                    }
10065                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10066
10067                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10068
10069                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10070                    for (int i=0; i<ris.size(); i++) {
10071                        ActivityInfo ai = ris.get(i).activityInfo;
10072                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10073                        if (lastDoneReceivers.contains(comp)) {
10074                            // We already did the pre boot receiver for this app with the current
10075                            // platform version, so don't do it again...
10076                            ris.remove(i);
10077                            i--;
10078                            // ...however, do keep it as one that has been done, so we don't
10079                            // forget about it when rewriting the file of last done receivers.
10080                            doneReceivers.add(comp);
10081                        }
10082                    }
10083
10084                    final int[] users = getUsersLocked();
10085                    for (int i=0; i<ris.size(); i++) {
10086                        ActivityInfo ai = ris.get(i).activityInfo;
10087                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10088                        doneReceivers.add(comp);
10089                        intent.setComponent(comp);
10090                        for (int j=0; j<users.length; j++) {
10091                            IIntentReceiver finisher = null;
10092                            if (i == ris.size()-1 && j == users.length-1) {
10093                                finisher = new IIntentReceiver.Stub() {
10094                                    public void performReceive(Intent intent, int resultCode,
10095                                            String data, Bundle extras, boolean ordered,
10096                                            boolean sticky, int sendingUser) {
10097                                        // The raw IIntentReceiver interface is called
10098                                        // with the AM lock held, so redispatch to
10099                                        // execute our code without the lock.
10100                                        mHandler.post(new Runnable() {
10101                                            public void run() {
10102                                                synchronized (ActivityManagerService.this) {
10103                                                    mDidUpdate = true;
10104                                                }
10105                                                writeLastDonePreBootReceivers(doneReceivers);
10106                                                showBootMessage(mContext.getText(
10107                                                        R.string.android_upgrading_complete),
10108                                                        false);
10109                                                systemReady(goingCallback);
10110                                            }
10111                                        });
10112                                    }
10113                                };
10114                            }
10115                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
10116                                    + " for user " + users[j]);
10117                            broadcastIntentLocked(null, null, intent, null, finisher,
10118                                    0, null, null, null, AppOpsManager.OP_NONE,
10119                                    true, false, MY_PID, Process.SYSTEM_UID,
10120                                    users[j]);
10121                            if (finisher != null) {
10122                                mWaitingUpdate = true;
10123                            }
10124                        }
10125                    }
10126                }
10127                if (mWaitingUpdate) {
10128                    return;
10129                }
10130                mDidUpdate = true;
10131            }
10132
10133            mAppOpsService.systemReady();
10134            mSystemReady = true;
10135        }
10136
10137        ArrayList<ProcessRecord> procsToKill = null;
10138        synchronized(mPidsSelfLocked) {
10139            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10140                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10141                if (!isAllowedWhileBooting(proc.info)){
10142                    if (procsToKill == null) {
10143                        procsToKill = new ArrayList<ProcessRecord>();
10144                    }
10145                    procsToKill.add(proc);
10146                }
10147            }
10148        }
10149
10150        synchronized(this) {
10151            if (procsToKill != null) {
10152                for (int i=procsToKill.size()-1; i>=0; i--) {
10153                    ProcessRecord proc = procsToKill.get(i);
10154                    Slog.i(TAG, "Removing system update proc: " + proc);
10155                    removeProcessLocked(proc, true, false, "system update done");
10156                }
10157            }
10158
10159            // Now that we have cleaned up any update processes, we
10160            // are ready to start launching real processes and know that
10161            // we won't trample on them any more.
10162            mProcessesReady = true;
10163        }
10164
10165        Slog.i(TAG, "System now ready");
10166        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10167            SystemClock.uptimeMillis());
10168
10169        synchronized(this) {
10170            // Make sure we have no pre-ready processes sitting around.
10171
10172            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10173                ResolveInfo ri = mContext.getPackageManager()
10174                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10175                                STOCK_PM_FLAGS);
10176                CharSequence errorMsg = null;
10177                if (ri != null) {
10178                    ActivityInfo ai = ri.activityInfo;
10179                    ApplicationInfo app = ai.applicationInfo;
10180                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10181                        mTopAction = Intent.ACTION_FACTORY_TEST;
10182                        mTopData = null;
10183                        mTopComponent = new ComponentName(app.packageName,
10184                                ai.name);
10185                    } else {
10186                        errorMsg = mContext.getResources().getText(
10187                                com.android.internal.R.string.factorytest_not_system);
10188                    }
10189                } else {
10190                    errorMsg = mContext.getResources().getText(
10191                            com.android.internal.R.string.factorytest_no_action);
10192                }
10193                if (errorMsg != null) {
10194                    mTopAction = null;
10195                    mTopData = null;
10196                    mTopComponent = null;
10197                    Message msg = Message.obtain();
10198                    msg.what = SHOW_FACTORY_ERROR_MSG;
10199                    msg.getData().putCharSequence("msg", errorMsg);
10200                    mHandler.sendMessage(msg);
10201                }
10202            }
10203        }
10204
10205        retrieveSettings();
10206
10207        synchronized (this) {
10208            readGrantedUriPermissionsLocked();
10209        }
10210
10211        if (goingCallback != null) goingCallback.run();
10212
10213        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10214                Integer.toString(mCurrentUserId), mCurrentUserId);
10215        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10216                Integer.toString(mCurrentUserId), mCurrentUserId);
10217        mSystemServiceManager.startUser(mCurrentUserId);
10218
10219        synchronized (this) {
10220            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10221                try {
10222                    List apps = AppGlobals.getPackageManager().
10223                        getPersistentApplications(STOCK_PM_FLAGS);
10224                    if (apps != null) {
10225                        int N = apps.size();
10226                        int i;
10227                        for (i=0; i<N; i++) {
10228                            ApplicationInfo info
10229                                = (ApplicationInfo)apps.get(i);
10230                            if (info != null &&
10231                                    !info.packageName.equals("android")) {
10232                                addAppLocked(info, false, null /* ABI override */);
10233                            }
10234                        }
10235                    }
10236                } catch (RemoteException ex) {
10237                    // pm is in same process, this will never happen.
10238                }
10239            }
10240
10241            // Start up initial activity.
10242            mBooting = true;
10243
10244            try {
10245                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10246                    Message msg = Message.obtain();
10247                    msg.what = SHOW_UID_ERROR_MSG;
10248                    mHandler.sendMessage(msg);
10249                }
10250            } catch (RemoteException e) {
10251            }
10252
10253            long ident = Binder.clearCallingIdentity();
10254            try {
10255                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10256                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10257                        | Intent.FLAG_RECEIVER_FOREGROUND);
10258                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10259                broadcastIntentLocked(null, null, intent,
10260                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10261                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10262                intent = new Intent(Intent.ACTION_USER_STARTING);
10263                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10264                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10265                broadcastIntentLocked(null, null, intent,
10266                        null, new IIntentReceiver.Stub() {
10267                            @Override
10268                            public void performReceive(Intent intent, int resultCode, String data,
10269                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10270                                    throws RemoteException {
10271                            }
10272                        }, 0, null, null,
10273                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10274                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10275            } catch (Throwable t) {
10276                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10277            } finally {
10278                Binder.restoreCallingIdentity(ident);
10279            }
10280            mStackSupervisor.resumeTopActivitiesLocked();
10281            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10282        }
10283    }
10284
10285    private boolean makeAppCrashingLocked(ProcessRecord app,
10286            String shortMsg, String longMsg, String stackTrace) {
10287        app.crashing = true;
10288        app.crashingReport = generateProcessError(app,
10289                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10290        startAppProblemLocked(app);
10291        app.stopFreezingAllLocked();
10292        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10293    }
10294
10295    private void makeAppNotRespondingLocked(ProcessRecord app,
10296            String activity, String shortMsg, String longMsg) {
10297        app.notResponding = true;
10298        app.notRespondingReport = generateProcessError(app,
10299                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10300                activity, shortMsg, longMsg, null);
10301        startAppProblemLocked(app);
10302        app.stopFreezingAllLocked();
10303    }
10304
10305    /**
10306     * Generate a process error record, suitable for attachment to a ProcessRecord.
10307     *
10308     * @param app The ProcessRecord in which the error occurred.
10309     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10310     *                      ActivityManager.AppErrorStateInfo
10311     * @param activity The activity associated with the crash, if known.
10312     * @param shortMsg Short message describing the crash.
10313     * @param longMsg Long message describing the crash.
10314     * @param stackTrace Full crash stack trace, may be null.
10315     *
10316     * @return Returns a fully-formed AppErrorStateInfo record.
10317     */
10318    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10319            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10320        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10321
10322        report.condition = condition;
10323        report.processName = app.processName;
10324        report.pid = app.pid;
10325        report.uid = app.info.uid;
10326        report.tag = activity;
10327        report.shortMsg = shortMsg;
10328        report.longMsg = longMsg;
10329        report.stackTrace = stackTrace;
10330
10331        return report;
10332    }
10333
10334    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10335        synchronized (this) {
10336            app.crashing = false;
10337            app.crashingReport = null;
10338            app.notResponding = false;
10339            app.notRespondingReport = null;
10340            if (app.anrDialog == fromDialog) {
10341                app.anrDialog = null;
10342            }
10343            if (app.waitDialog == fromDialog) {
10344                app.waitDialog = null;
10345            }
10346            if (app.pid > 0 && app.pid != MY_PID) {
10347                handleAppCrashLocked(app, null, null, null);
10348                killUnneededProcessLocked(app, "user request after error");
10349            }
10350        }
10351    }
10352
10353    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10354            String stackTrace) {
10355        long now = SystemClock.uptimeMillis();
10356
10357        Long crashTime;
10358        if (!app.isolated) {
10359            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10360        } else {
10361            crashTime = null;
10362        }
10363        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10364            // This process loses!
10365            Slog.w(TAG, "Process " + app.info.processName
10366                    + " has crashed too many times: killing!");
10367            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10368                    app.userId, app.info.processName, app.uid);
10369            mStackSupervisor.handleAppCrashLocked(app);
10370            if (!app.persistent) {
10371                // We don't want to start this process again until the user
10372                // explicitly does so...  but for persistent process, we really
10373                // need to keep it running.  If a persistent process is actually
10374                // repeatedly crashing, then badness for everyone.
10375                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10376                        app.info.processName);
10377                if (!app.isolated) {
10378                    // XXX We don't have a way to mark isolated processes
10379                    // as bad, since they don't have a peristent identity.
10380                    mBadProcesses.put(app.info.processName, app.uid,
10381                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10382                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10383                }
10384                app.bad = true;
10385                app.removed = true;
10386                // Don't let services in this process be restarted and potentially
10387                // annoy the user repeatedly.  Unless it is persistent, since those
10388                // processes run critical code.
10389                removeProcessLocked(app, false, false, "crash");
10390                mStackSupervisor.resumeTopActivitiesLocked();
10391                return false;
10392            }
10393            mStackSupervisor.resumeTopActivitiesLocked();
10394        } else {
10395            mStackSupervisor.finishTopRunningActivityLocked(app);
10396        }
10397
10398        // Bump up the crash count of any services currently running in the proc.
10399        for (int i=app.services.size()-1; i>=0; i--) {
10400            // Any services running in the application need to be placed
10401            // back in the pending list.
10402            ServiceRecord sr = app.services.valueAt(i);
10403            sr.crashCount++;
10404        }
10405
10406        // If the crashing process is what we consider to be the "home process" and it has been
10407        // replaced by a third-party app, clear the package preferred activities from packages
10408        // with a home activity running in the process to prevent a repeatedly crashing app
10409        // from blocking the user to manually clear the list.
10410        final ArrayList<ActivityRecord> activities = app.activities;
10411        if (app == mHomeProcess && activities.size() > 0
10412                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10413            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10414                final ActivityRecord r = activities.get(activityNdx);
10415                if (r.isHomeActivity()) {
10416                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10417                    try {
10418                        ActivityThread.getPackageManager()
10419                                .clearPackagePreferredActivities(r.packageName);
10420                    } catch (RemoteException c) {
10421                        // pm is in same process, this will never happen.
10422                    }
10423                }
10424            }
10425        }
10426
10427        if (!app.isolated) {
10428            // XXX Can't keep track of crash times for isolated processes,
10429            // because they don't have a perisistent identity.
10430            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10431        }
10432
10433        return true;
10434    }
10435
10436    void startAppProblemLocked(ProcessRecord app) {
10437        if (app.userId == mCurrentUserId) {
10438            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10439                    mContext, app.info.packageName, app.info.flags);
10440        } else {
10441            // If this app is not running under the current user, then we
10442            // can't give it a report button because that would require
10443            // launching the report UI under a different user.
10444            app.errorReportReceiver = null;
10445        }
10446        skipCurrentReceiverLocked(app);
10447    }
10448
10449    void skipCurrentReceiverLocked(ProcessRecord app) {
10450        for (BroadcastQueue queue : mBroadcastQueues) {
10451            queue.skipCurrentReceiverLocked(app);
10452        }
10453    }
10454
10455    /**
10456     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10457     * The application process will exit immediately after this call returns.
10458     * @param app object of the crashing app, null for the system server
10459     * @param crashInfo describing the exception
10460     */
10461    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10462        ProcessRecord r = findAppProcess(app, "Crash");
10463        final String processName = app == null ? "system_server"
10464                : (r == null ? "unknown" : r.processName);
10465
10466        handleApplicationCrashInner("crash", r, processName, crashInfo);
10467    }
10468
10469    /* Native crash reporting uses this inner version because it needs to be somewhat
10470     * decoupled from the AM-managed cleanup lifecycle
10471     */
10472    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10473            ApplicationErrorReport.CrashInfo crashInfo) {
10474        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10475                UserHandle.getUserId(Binder.getCallingUid()), processName,
10476                r == null ? -1 : r.info.flags,
10477                crashInfo.exceptionClassName,
10478                crashInfo.exceptionMessage,
10479                crashInfo.throwFileName,
10480                crashInfo.throwLineNumber);
10481
10482        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10483
10484        crashApplication(r, crashInfo);
10485    }
10486
10487    public void handleApplicationStrictModeViolation(
10488            IBinder app,
10489            int violationMask,
10490            StrictMode.ViolationInfo info) {
10491        ProcessRecord r = findAppProcess(app, "StrictMode");
10492        if (r == null) {
10493            return;
10494        }
10495
10496        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10497            Integer stackFingerprint = info.hashCode();
10498            boolean logIt = true;
10499            synchronized (mAlreadyLoggedViolatedStacks) {
10500                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10501                    logIt = false;
10502                    // TODO: sub-sample into EventLog for these, with
10503                    // the info.durationMillis?  Then we'd get
10504                    // the relative pain numbers, without logging all
10505                    // the stack traces repeatedly.  We'd want to do
10506                    // likewise in the client code, which also does
10507                    // dup suppression, before the Binder call.
10508                } else {
10509                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10510                        mAlreadyLoggedViolatedStacks.clear();
10511                    }
10512                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10513                }
10514            }
10515            if (logIt) {
10516                logStrictModeViolationToDropBox(r, info);
10517            }
10518        }
10519
10520        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10521            AppErrorResult result = new AppErrorResult();
10522            synchronized (this) {
10523                final long origId = Binder.clearCallingIdentity();
10524
10525                Message msg = Message.obtain();
10526                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10527                HashMap<String, Object> data = new HashMap<String, Object>();
10528                data.put("result", result);
10529                data.put("app", r);
10530                data.put("violationMask", violationMask);
10531                data.put("info", info);
10532                msg.obj = data;
10533                mHandler.sendMessage(msg);
10534
10535                Binder.restoreCallingIdentity(origId);
10536            }
10537            int res = result.get();
10538            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10539        }
10540    }
10541
10542    // Depending on the policy in effect, there could be a bunch of
10543    // these in quick succession so we try to batch these together to
10544    // minimize disk writes, number of dropbox entries, and maximize
10545    // compression, by having more fewer, larger records.
10546    private void logStrictModeViolationToDropBox(
10547            ProcessRecord process,
10548            StrictMode.ViolationInfo info) {
10549        if (info == null) {
10550            return;
10551        }
10552        final boolean isSystemApp = process == null ||
10553                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10554                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10555        final String processName = process == null ? "unknown" : process.processName;
10556        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10557        final DropBoxManager dbox = (DropBoxManager)
10558                mContext.getSystemService(Context.DROPBOX_SERVICE);
10559
10560        // Exit early if the dropbox isn't configured to accept this report type.
10561        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10562
10563        boolean bufferWasEmpty;
10564        boolean needsFlush;
10565        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10566        synchronized (sb) {
10567            bufferWasEmpty = sb.length() == 0;
10568            appendDropBoxProcessHeaders(process, processName, sb);
10569            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10570            sb.append("System-App: ").append(isSystemApp).append("\n");
10571            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10572            if (info.violationNumThisLoop != 0) {
10573                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10574            }
10575            if (info.numAnimationsRunning != 0) {
10576                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10577            }
10578            if (info.broadcastIntentAction != null) {
10579                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10580            }
10581            if (info.durationMillis != -1) {
10582                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10583            }
10584            if (info.numInstances != -1) {
10585                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10586            }
10587            if (info.tags != null) {
10588                for (String tag : info.tags) {
10589                    sb.append("Span-Tag: ").append(tag).append("\n");
10590                }
10591            }
10592            sb.append("\n");
10593            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10594                sb.append(info.crashInfo.stackTrace);
10595            }
10596            sb.append("\n");
10597
10598            // Only buffer up to ~64k.  Various logging bits truncate
10599            // things at 128k.
10600            needsFlush = (sb.length() > 64 * 1024);
10601        }
10602
10603        // Flush immediately if the buffer's grown too large, or this
10604        // is a non-system app.  Non-system apps are isolated with a
10605        // different tag & policy and not batched.
10606        //
10607        // Batching is useful during internal testing with
10608        // StrictMode settings turned up high.  Without batching,
10609        // thousands of separate files could be created on boot.
10610        if (!isSystemApp || needsFlush) {
10611            new Thread("Error dump: " + dropboxTag) {
10612                @Override
10613                public void run() {
10614                    String report;
10615                    synchronized (sb) {
10616                        report = sb.toString();
10617                        sb.delete(0, sb.length());
10618                        sb.trimToSize();
10619                    }
10620                    if (report.length() != 0) {
10621                        dbox.addText(dropboxTag, report);
10622                    }
10623                }
10624            }.start();
10625            return;
10626        }
10627
10628        // System app batching:
10629        if (!bufferWasEmpty) {
10630            // An existing dropbox-writing thread is outstanding, so
10631            // we don't need to start it up.  The existing thread will
10632            // catch the buffer appends we just did.
10633            return;
10634        }
10635
10636        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10637        // (After this point, we shouldn't access AMS internal data structures.)
10638        new Thread("Error dump: " + dropboxTag) {
10639            @Override
10640            public void run() {
10641                // 5 second sleep to let stacks arrive and be batched together
10642                try {
10643                    Thread.sleep(5000);  // 5 seconds
10644                } catch (InterruptedException e) {}
10645
10646                String errorReport;
10647                synchronized (mStrictModeBuffer) {
10648                    errorReport = mStrictModeBuffer.toString();
10649                    if (errorReport.length() == 0) {
10650                        return;
10651                    }
10652                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10653                    mStrictModeBuffer.trimToSize();
10654                }
10655                dbox.addText(dropboxTag, errorReport);
10656            }
10657        }.start();
10658    }
10659
10660    /**
10661     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10662     * @param app object of the crashing app, null for the system server
10663     * @param tag reported by the caller
10664     * @param crashInfo describing the context of the error
10665     * @return true if the process should exit immediately (WTF is fatal)
10666     */
10667    public boolean handleApplicationWtf(IBinder app, String tag,
10668            ApplicationErrorReport.CrashInfo crashInfo) {
10669        ProcessRecord r = findAppProcess(app, "WTF");
10670        final String processName = app == null ? "system_server"
10671                : (r == null ? "unknown" : r.processName);
10672
10673        EventLog.writeEvent(EventLogTags.AM_WTF,
10674                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10675                processName,
10676                r == null ? -1 : r.info.flags,
10677                tag, crashInfo.exceptionMessage);
10678
10679        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10680
10681        if (r != null && r.pid != Process.myPid() &&
10682                Settings.Global.getInt(mContext.getContentResolver(),
10683                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10684            crashApplication(r, crashInfo);
10685            return true;
10686        } else {
10687            return false;
10688        }
10689    }
10690
10691    /**
10692     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10693     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10694     */
10695    private ProcessRecord findAppProcess(IBinder app, String reason) {
10696        if (app == null) {
10697            return null;
10698        }
10699
10700        synchronized (this) {
10701            final int NP = mProcessNames.getMap().size();
10702            for (int ip=0; ip<NP; ip++) {
10703                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10704                final int NA = apps.size();
10705                for (int ia=0; ia<NA; ia++) {
10706                    ProcessRecord p = apps.valueAt(ia);
10707                    if (p.thread != null && p.thread.asBinder() == app) {
10708                        return p;
10709                    }
10710                }
10711            }
10712
10713            Slog.w(TAG, "Can't find mystery application for " + reason
10714                    + " from pid=" + Binder.getCallingPid()
10715                    + " uid=" + Binder.getCallingUid() + ": " + app);
10716            return null;
10717        }
10718    }
10719
10720    /**
10721     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10722     * to append various headers to the dropbox log text.
10723     */
10724    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10725            StringBuilder sb) {
10726        // Watchdog thread ends up invoking this function (with
10727        // a null ProcessRecord) to add the stack file to dropbox.
10728        // Do not acquire a lock on this (am) in such cases, as it
10729        // could cause a potential deadlock, if and when watchdog
10730        // is invoked due to unavailability of lock on am and it
10731        // would prevent watchdog from killing system_server.
10732        if (process == null) {
10733            sb.append("Process: ").append(processName).append("\n");
10734            return;
10735        }
10736        // Note: ProcessRecord 'process' is guarded by the service
10737        // instance.  (notably process.pkgList, which could otherwise change
10738        // concurrently during execution of this method)
10739        synchronized (this) {
10740            sb.append("Process: ").append(processName).append("\n");
10741            int flags = process.info.flags;
10742            IPackageManager pm = AppGlobals.getPackageManager();
10743            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10744            for (int ip=0; ip<process.pkgList.size(); ip++) {
10745                String pkg = process.pkgList.keyAt(ip);
10746                sb.append("Package: ").append(pkg);
10747                try {
10748                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10749                    if (pi != null) {
10750                        sb.append(" v").append(pi.versionCode);
10751                        if (pi.versionName != null) {
10752                            sb.append(" (").append(pi.versionName).append(")");
10753                        }
10754                    }
10755                } catch (RemoteException e) {
10756                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10757                }
10758                sb.append("\n");
10759            }
10760        }
10761    }
10762
10763    private static String processClass(ProcessRecord process) {
10764        if (process == null || process.pid == MY_PID) {
10765            return "system_server";
10766        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10767            return "system_app";
10768        } else {
10769            return "data_app";
10770        }
10771    }
10772
10773    /**
10774     * Write a description of an error (crash, WTF, ANR) to the drop box.
10775     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10776     * @param process which caused the error, null means the system server
10777     * @param activity which triggered the error, null if unknown
10778     * @param parent activity related to the error, null if unknown
10779     * @param subject line related to the error, null if absent
10780     * @param report in long form describing the error, null if absent
10781     * @param logFile to include in the report, null if none
10782     * @param crashInfo giving an application stack trace, null if absent
10783     */
10784    public void addErrorToDropBox(String eventType,
10785            ProcessRecord process, String processName, ActivityRecord activity,
10786            ActivityRecord parent, String subject,
10787            final String report, final File logFile,
10788            final ApplicationErrorReport.CrashInfo crashInfo) {
10789        // NOTE -- this must never acquire the ActivityManagerService lock,
10790        // otherwise the watchdog may be prevented from resetting the system.
10791
10792        final String dropboxTag = processClass(process) + "_" + eventType;
10793        final DropBoxManager dbox = (DropBoxManager)
10794                mContext.getSystemService(Context.DROPBOX_SERVICE);
10795
10796        // Exit early if the dropbox isn't configured to accept this report type.
10797        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10798
10799        final StringBuilder sb = new StringBuilder(1024);
10800        appendDropBoxProcessHeaders(process, processName, sb);
10801        if (activity != null) {
10802            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10803        }
10804        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10805            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10806        }
10807        if (parent != null && parent != activity) {
10808            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10809        }
10810        if (subject != null) {
10811            sb.append("Subject: ").append(subject).append("\n");
10812        }
10813        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10814        if (Debug.isDebuggerConnected()) {
10815            sb.append("Debugger: Connected\n");
10816        }
10817        sb.append("\n");
10818
10819        // Do the rest in a worker thread to avoid blocking the caller on I/O
10820        // (After this point, we shouldn't access AMS internal data structures.)
10821        Thread worker = new Thread("Error dump: " + dropboxTag) {
10822            @Override
10823            public void run() {
10824                if (report != null) {
10825                    sb.append(report);
10826                }
10827                if (logFile != null) {
10828                    try {
10829                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10830                                    "\n\n[[TRUNCATED]]"));
10831                    } catch (IOException e) {
10832                        Slog.e(TAG, "Error reading " + logFile, e);
10833                    }
10834                }
10835                if (crashInfo != null && crashInfo.stackTrace != null) {
10836                    sb.append(crashInfo.stackTrace);
10837                }
10838
10839                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10840                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10841                if (lines > 0) {
10842                    sb.append("\n");
10843
10844                    // Merge several logcat streams, and take the last N lines
10845                    InputStreamReader input = null;
10846                    try {
10847                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10848                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10849                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10850
10851                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10852                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10853                        input = new InputStreamReader(logcat.getInputStream());
10854
10855                        int num;
10856                        char[] buf = new char[8192];
10857                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10858                    } catch (IOException e) {
10859                        Slog.e(TAG, "Error running logcat", e);
10860                    } finally {
10861                        if (input != null) try { input.close(); } catch (IOException e) {}
10862                    }
10863                }
10864
10865                dbox.addText(dropboxTag, sb.toString());
10866            }
10867        };
10868
10869        if (process == null) {
10870            // If process is null, we are being called from some internal code
10871            // and may be about to die -- run this synchronously.
10872            worker.run();
10873        } else {
10874            worker.start();
10875        }
10876    }
10877
10878    /**
10879     * Bring up the "unexpected error" dialog box for a crashing app.
10880     * Deal with edge cases (intercepts from instrumented applications,
10881     * ActivityController, error intent receivers, that sort of thing).
10882     * @param r the application crashing
10883     * @param crashInfo describing the failure
10884     */
10885    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10886        long timeMillis = System.currentTimeMillis();
10887        String shortMsg = crashInfo.exceptionClassName;
10888        String longMsg = crashInfo.exceptionMessage;
10889        String stackTrace = crashInfo.stackTrace;
10890        if (shortMsg != null && longMsg != null) {
10891            longMsg = shortMsg + ": " + longMsg;
10892        } else if (shortMsg != null) {
10893            longMsg = shortMsg;
10894        }
10895
10896        AppErrorResult result = new AppErrorResult();
10897        synchronized (this) {
10898            if (mController != null) {
10899                try {
10900                    String name = r != null ? r.processName : null;
10901                    int pid = r != null ? r.pid : Binder.getCallingPid();
10902                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10903                    if (!mController.appCrashed(name, pid,
10904                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10905                        Slog.w(TAG, "Force-killing crashed app " + name
10906                                + " at watcher's request");
10907                        Process.killProcess(pid);
10908                        if (r != null) {
10909                            Process.killProcessGroup(uid, pid);
10910                        }
10911                        return;
10912                    }
10913                } catch (RemoteException e) {
10914                    mController = null;
10915                    Watchdog.getInstance().setActivityController(null);
10916                }
10917            }
10918
10919            final long origId = Binder.clearCallingIdentity();
10920
10921            // If this process is running instrumentation, finish it.
10922            if (r != null && r.instrumentationClass != null) {
10923                Slog.w(TAG, "Error in app " + r.processName
10924                      + " running instrumentation " + r.instrumentationClass + ":");
10925                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10926                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10927                Bundle info = new Bundle();
10928                info.putString("shortMsg", shortMsg);
10929                info.putString("longMsg", longMsg);
10930                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10931                Binder.restoreCallingIdentity(origId);
10932                return;
10933            }
10934
10935            // If we can't identify the process or it's already exceeded its crash quota,
10936            // quit right away without showing a crash dialog.
10937            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10938                Binder.restoreCallingIdentity(origId);
10939                return;
10940            }
10941
10942            Message msg = Message.obtain();
10943            msg.what = SHOW_ERROR_MSG;
10944            HashMap data = new HashMap();
10945            data.put("result", result);
10946            data.put("app", r);
10947            msg.obj = data;
10948            mHandler.sendMessage(msg);
10949
10950            Binder.restoreCallingIdentity(origId);
10951        }
10952
10953        int res = result.get();
10954
10955        Intent appErrorIntent = null;
10956        synchronized (this) {
10957            if (r != null && !r.isolated) {
10958                // XXX Can't keep track of crash time for isolated processes,
10959                // since they don't have a persistent identity.
10960                mProcessCrashTimes.put(r.info.processName, r.uid,
10961                        SystemClock.uptimeMillis());
10962            }
10963            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10964                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10965            }
10966        }
10967
10968        if (appErrorIntent != null) {
10969            try {
10970                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10971            } catch (ActivityNotFoundException e) {
10972                Slog.w(TAG, "bug report receiver dissappeared", e);
10973            }
10974        }
10975    }
10976
10977    Intent createAppErrorIntentLocked(ProcessRecord r,
10978            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10979        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10980        if (report == null) {
10981            return null;
10982        }
10983        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10984        result.setComponent(r.errorReportReceiver);
10985        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10986        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10987        return result;
10988    }
10989
10990    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10991            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10992        if (r.errorReportReceiver == null) {
10993            return null;
10994        }
10995
10996        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10997            return null;
10998        }
10999
11000        ApplicationErrorReport report = new ApplicationErrorReport();
11001        report.packageName = r.info.packageName;
11002        report.installerPackageName = r.errorReportReceiver.getPackageName();
11003        report.processName = r.processName;
11004        report.time = timeMillis;
11005        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11006
11007        if (r.crashing || r.forceCrashReport) {
11008            report.type = ApplicationErrorReport.TYPE_CRASH;
11009            report.crashInfo = crashInfo;
11010        } else if (r.notResponding) {
11011            report.type = ApplicationErrorReport.TYPE_ANR;
11012            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11013
11014            report.anrInfo.activity = r.notRespondingReport.tag;
11015            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11016            report.anrInfo.info = r.notRespondingReport.longMsg;
11017        }
11018
11019        return report;
11020    }
11021
11022    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11023        enforceNotIsolatedCaller("getProcessesInErrorState");
11024        // assume our apps are happy - lazy create the list
11025        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11026
11027        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11028                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11029        int userId = UserHandle.getUserId(Binder.getCallingUid());
11030
11031        synchronized (this) {
11032
11033            // iterate across all processes
11034            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11035                ProcessRecord app = mLruProcesses.get(i);
11036                if (!allUsers && app.userId != userId) {
11037                    continue;
11038                }
11039                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11040                    // This one's in trouble, so we'll generate a report for it
11041                    // crashes are higher priority (in case there's a crash *and* an anr)
11042                    ActivityManager.ProcessErrorStateInfo report = null;
11043                    if (app.crashing) {
11044                        report = app.crashingReport;
11045                    } else if (app.notResponding) {
11046                        report = app.notRespondingReport;
11047                    }
11048
11049                    if (report != null) {
11050                        if (errList == null) {
11051                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11052                        }
11053                        errList.add(report);
11054                    } else {
11055                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11056                                " crashing = " + app.crashing +
11057                                " notResponding = " + app.notResponding);
11058                    }
11059                }
11060            }
11061        }
11062
11063        return errList;
11064    }
11065
11066    static int procStateToImportance(int procState, int memAdj,
11067            ActivityManager.RunningAppProcessInfo currApp) {
11068        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11069        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11070            currApp.lru = memAdj;
11071        } else {
11072            currApp.lru = 0;
11073        }
11074        return imp;
11075    }
11076
11077    private void fillInProcMemInfo(ProcessRecord app,
11078            ActivityManager.RunningAppProcessInfo outInfo) {
11079        outInfo.pid = app.pid;
11080        outInfo.uid = app.info.uid;
11081        if (mHeavyWeightProcess == app) {
11082            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11083        }
11084        if (app.persistent) {
11085            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11086        }
11087        if (app.activities.size() > 0) {
11088            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11089        }
11090        outInfo.lastTrimLevel = app.trimMemoryLevel;
11091        int adj = app.curAdj;
11092        int procState = app.curProcState;
11093        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11094        outInfo.importanceReasonCode = app.adjTypeCode;
11095        outInfo.processState = app.curProcState;
11096    }
11097
11098    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11099        enforceNotIsolatedCaller("getRunningAppProcesses");
11100        // Lazy instantiation of list
11101        List<ActivityManager.RunningAppProcessInfo> runList = null;
11102        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11103                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11104        int userId = UserHandle.getUserId(Binder.getCallingUid());
11105        synchronized (this) {
11106            // Iterate across all processes
11107            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11108                ProcessRecord app = mLruProcesses.get(i);
11109                if (!allUsers && app.userId != userId) {
11110                    continue;
11111                }
11112                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11113                    // Generate process state info for running application
11114                    ActivityManager.RunningAppProcessInfo currApp =
11115                        new ActivityManager.RunningAppProcessInfo(app.processName,
11116                                app.pid, app.getPackageList());
11117                    fillInProcMemInfo(app, currApp);
11118                    if (app.adjSource instanceof ProcessRecord) {
11119                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11120                        currApp.importanceReasonImportance =
11121                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11122                                        app.adjSourceProcState);
11123                    } else if (app.adjSource instanceof ActivityRecord) {
11124                        ActivityRecord r = (ActivityRecord)app.adjSource;
11125                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11126                    }
11127                    if (app.adjTarget instanceof ComponentName) {
11128                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11129                    }
11130                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11131                    //        + " lru=" + currApp.lru);
11132                    if (runList == null) {
11133                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11134                    }
11135                    runList.add(currApp);
11136                }
11137            }
11138        }
11139        return runList;
11140    }
11141
11142    public List<ApplicationInfo> getRunningExternalApplications() {
11143        enforceNotIsolatedCaller("getRunningExternalApplications");
11144        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11145        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11146        if (runningApps != null && runningApps.size() > 0) {
11147            Set<String> extList = new HashSet<String>();
11148            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11149                if (app.pkgList != null) {
11150                    for (String pkg : app.pkgList) {
11151                        extList.add(pkg);
11152                    }
11153                }
11154            }
11155            IPackageManager pm = AppGlobals.getPackageManager();
11156            for (String pkg : extList) {
11157                try {
11158                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11159                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11160                        retList.add(info);
11161                    }
11162                } catch (RemoteException e) {
11163                }
11164            }
11165        }
11166        return retList;
11167    }
11168
11169    @Override
11170    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11171        enforceNotIsolatedCaller("getMyMemoryState");
11172        synchronized (this) {
11173            ProcessRecord proc;
11174            synchronized (mPidsSelfLocked) {
11175                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11176            }
11177            fillInProcMemInfo(proc, outInfo);
11178        }
11179    }
11180
11181    @Override
11182    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11183        if (checkCallingPermission(android.Manifest.permission.DUMP)
11184                != PackageManager.PERMISSION_GRANTED) {
11185            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11186                    + Binder.getCallingPid()
11187                    + ", uid=" + Binder.getCallingUid()
11188                    + " without permission "
11189                    + android.Manifest.permission.DUMP);
11190            return;
11191        }
11192
11193        boolean dumpAll = false;
11194        boolean dumpClient = false;
11195        String dumpPackage = null;
11196
11197        int opti = 0;
11198        while (opti < args.length) {
11199            String opt = args[opti];
11200            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11201                break;
11202            }
11203            opti++;
11204            if ("-a".equals(opt)) {
11205                dumpAll = true;
11206            } else if ("-c".equals(opt)) {
11207                dumpClient = true;
11208            } else if ("-h".equals(opt)) {
11209                pw.println("Activity manager dump options:");
11210                pw.println("  [-a] [-c] [-h] [cmd] ...");
11211                pw.println("  cmd may be one of:");
11212                pw.println("    a[ctivities]: activity stack state");
11213                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11214                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11215                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11216                pw.println("    o[om]: out of memory management");
11217                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11218                pw.println("    provider [COMP_SPEC]: provider client-side state");
11219                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11220                pw.println("    service [COMP_SPEC]: service client-side state");
11221                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11222                pw.println("    all: dump all activities");
11223                pw.println("    top: dump the top activity");
11224                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11225                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11226                pw.println("    a partial substring in a component name, a");
11227                pw.println("    hex object identifier.");
11228                pw.println("  -a: include all available server state.");
11229                pw.println("  -c: include client state.");
11230                return;
11231            } else {
11232                pw.println("Unknown argument: " + opt + "; use -h for help");
11233            }
11234        }
11235
11236        long origId = Binder.clearCallingIdentity();
11237        boolean more = false;
11238        // Is the caller requesting to dump a particular piece of data?
11239        if (opti < args.length) {
11240            String cmd = args[opti];
11241            opti++;
11242            if ("activities".equals(cmd) || "a".equals(cmd)) {
11243                synchronized (this) {
11244                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11245                }
11246            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11247                String[] newArgs;
11248                String name;
11249                if (opti >= args.length) {
11250                    name = null;
11251                    newArgs = EMPTY_STRING_ARRAY;
11252                } else {
11253                    name = args[opti];
11254                    opti++;
11255                    newArgs = new String[args.length - opti];
11256                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11257                            args.length - opti);
11258                }
11259                synchronized (this) {
11260                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11261                }
11262            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11263                String[] newArgs;
11264                String name;
11265                if (opti >= args.length) {
11266                    name = null;
11267                    newArgs = EMPTY_STRING_ARRAY;
11268                } else {
11269                    name = args[opti];
11270                    opti++;
11271                    newArgs = new String[args.length - opti];
11272                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11273                            args.length - opti);
11274                }
11275                synchronized (this) {
11276                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11277                }
11278            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11279                String[] newArgs;
11280                String name;
11281                if (opti >= args.length) {
11282                    name = null;
11283                    newArgs = EMPTY_STRING_ARRAY;
11284                } else {
11285                    name = args[opti];
11286                    opti++;
11287                    newArgs = new String[args.length - opti];
11288                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11289                            args.length - opti);
11290                }
11291                synchronized (this) {
11292                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11293                }
11294            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11295                synchronized (this) {
11296                    dumpOomLocked(fd, pw, args, opti, true);
11297                }
11298            } else if ("provider".equals(cmd)) {
11299                String[] newArgs;
11300                String name;
11301                if (opti >= args.length) {
11302                    name = null;
11303                    newArgs = EMPTY_STRING_ARRAY;
11304                } else {
11305                    name = args[opti];
11306                    opti++;
11307                    newArgs = new String[args.length - opti];
11308                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11309                }
11310                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11311                    pw.println("No providers match: " + name);
11312                    pw.println("Use -h for help.");
11313                }
11314            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11315                synchronized (this) {
11316                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11317                }
11318            } else if ("service".equals(cmd)) {
11319                String[] newArgs;
11320                String name;
11321                if (opti >= args.length) {
11322                    name = null;
11323                    newArgs = EMPTY_STRING_ARRAY;
11324                } else {
11325                    name = args[opti];
11326                    opti++;
11327                    newArgs = new String[args.length - opti];
11328                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11329                            args.length - opti);
11330                }
11331                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11332                    pw.println("No services match: " + name);
11333                    pw.println("Use -h for help.");
11334                }
11335            } else if ("package".equals(cmd)) {
11336                String[] newArgs;
11337                if (opti >= args.length) {
11338                    pw.println("package: no package name specified");
11339                    pw.println("Use -h for help.");
11340                } else {
11341                    dumpPackage = args[opti];
11342                    opti++;
11343                    newArgs = new String[args.length - opti];
11344                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11345                            args.length - opti);
11346                    args = newArgs;
11347                    opti = 0;
11348                    more = true;
11349                }
11350            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11351                synchronized (this) {
11352                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11353                }
11354            } else {
11355                // Dumping a single activity?
11356                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11357                    pw.println("Bad activity command, or no activities match: " + cmd);
11358                    pw.println("Use -h for help.");
11359                }
11360            }
11361            if (!more) {
11362                Binder.restoreCallingIdentity(origId);
11363                return;
11364            }
11365        }
11366
11367        // No piece of data specified, dump everything.
11368        synchronized (this) {
11369            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11370            pw.println();
11371            if (dumpAll) {
11372                pw.println("-------------------------------------------------------------------------------");
11373            }
11374            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11375            pw.println();
11376            if (dumpAll) {
11377                pw.println("-------------------------------------------------------------------------------");
11378            }
11379            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11380            pw.println();
11381            if (dumpAll) {
11382                pw.println("-------------------------------------------------------------------------------");
11383            }
11384            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11385            pw.println();
11386            if (dumpAll) {
11387                pw.println("-------------------------------------------------------------------------------");
11388            }
11389            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11390            pw.println();
11391            if (dumpAll) {
11392                pw.println("-------------------------------------------------------------------------------");
11393            }
11394            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11395        }
11396        Binder.restoreCallingIdentity(origId);
11397    }
11398
11399    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11400            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11401        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11402
11403        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11404                dumpPackage);
11405        boolean needSep = printedAnything;
11406
11407        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11408                dumpPackage, needSep, "  mFocusedActivity: ");
11409        if (printed) {
11410            printedAnything = true;
11411            needSep = false;
11412        }
11413
11414        if (dumpPackage == null) {
11415            if (needSep) {
11416                pw.println();
11417            }
11418            needSep = true;
11419            printedAnything = true;
11420            mStackSupervisor.dump(pw, "  ");
11421        }
11422
11423        if (mRecentTasks.size() > 0) {
11424            boolean printedHeader = false;
11425
11426            final int N = mRecentTasks.size();
11427            for (int i=0; i<N; i++) {
11428                TaskRecord tr = mRecentTasks.get(i);
11429                if (dumpPackage != null) {
11430                    if (tr.realActivity == null ||
11431                            !dumpPackage.equals(tr.realActivity)) {
11432                        continue;
11433                    }
11434                }
11435                if (!printedHeader) {
11436                    if (needSep) {
11437                        pw.println();
11438                    }
11439                    pw.println("  Recent tasks:");
11440                    printedHeader = true;
11441                    printedAnything = true;
11442                }
11443                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11444                        pw.println(tr);
11445                if (dumpAll) {
11446                    mRecentTasks.get(i).dump(pw, "    ");
11447                }
11448            }
11449        }
11450
11451        if (!printedAnything) {
11452            pw.println("  (nothing)");
11453        }
11454    }
11455
11456    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11457            int opti, boolean dumpAll, String dumpPackage) {
11458        boolean needSep = false;
11459        boolean printedAnything = false;
11460        int numPers = 0;
11461
11462        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11463
11464        if (dumpAll) {
11465            final int NP = mProcessNames.getMap().size();
11466            for (int ip=0; ip<NP; ip++) {
11467                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11468                final int NA = procs.size();
11469                for (int ia=0; ia<NA; ia++) {
11470                    ProcessRecord r = procs.valueAt(ia);
11471                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11472                        continue;
11473                    }
11474                    if (!needSep) {
11475                        pw.println("  All known processes:");
11476                        needSep = true;
11477                        printedAnything = true;
11478                    }
11479                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11480                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11481                        pw.print(" "); pw.println(r);
11482                    r.dump(pw, "    ");
11483                    if (r.persistent) {
11484                        numPers++;
11485                    }
11486                }
11487            }
11488        }
11489
11490        if (mIsolatedProcesses.size() > 0) {
11491            boolean printed = false;
11492            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11493                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11494                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11495                    continue;
11496                }
11497                if (!printed) {
11498                    if (needSep) {
11499                        pw.println();
11500                    }
11501                    pw.println("  Isolated process list (sorted by uid):");
11502                    printedAnything = true;
11503                    printed = true;
11504                    needSep = true;
11505                }
11506                pw.println(String.format("%sIsolated #%2d: %s",
11507                        "    ", i, r.toString()));
11508            }
11509        }
11510
11511        if (mLruProcesses.size() > 0) {
11512            if (needSep) {
11513                pw.println();
11514            }
11515            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11516                    pw.print(" total, non-act at ");
11517                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11518                    pw.print(", non-svc at ");
11519                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11520                    pw.println("):");
11521            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11522            needSep = true;
11523            printedAnything = true;
11524        }
11525
11526        if (dumpAll || dumpPackage != null) {
11527            synchronized (mPidsSelfLocked) {
11528                boolean printed = false;
11529                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11530                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11531                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11532                        continue;
11533                    }
11534                    if (!printed) {
11535                        if (needSep) pw.println();
11536                        needSep = true;
11537                        pw.println("  PID mappings:");
11538                        printed = true;
11539                        printedAnything = true;
11540                    }
11541                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11542                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11543                }
11544            }
11545        }
11546
11547        if (mForegroundProcesses.size() > 0) {
11548            synchronized (mPidsSelfLocked) {
11549                boolean printed = false;
11550                for (int i=0; i<mForegroundProcesses.size(); i++) {
11551                    ProcessRecord r = mPidsSelfLocked.get(
11552                            mForegroundProcesses.valueAt(i).pid);
11553                    if (dumpPackage != null && (r == null
11554                            || !r.pkgList.containsKey(dumpPackage))) {
11555                        continue;
11556                    }
11557                    if (!printed) {
11558                        if (needSep) pw.println();
11559                        needSep = true;
11560                        pw.println("  Foreground Processes:");
11561                        printed = true;
11562                        printedAnything = true;
11563                    }
11564                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11565                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11566                }
11567            }
11568        }
11569
11570        if (mPersistentStartingProcesses.size() > 0) {
11571            if (needSep) pw.println();
11572            needSep = true;
11573            printedAnything = true;
11574            pw.println("  Persisent processes that are starting:");
11575            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11576                    "Starting Norm", "Restarting PERS", dumpPackage);
11577        }
11578
11579        if (mRemovedProcesses.size() > 0) {
11580            if (needSep) pw.println();
11581            needSep = true;
11582            printedAnything = true;
11583            pw.println("  Processes that are being removed:");
11584            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11585                    "Removed Norm", "Removed PERS", dumpPackage);
11586        }
11587
11588        if (mProcessesOnHold.size() > 0) {
11589            if (needSep) pw.println();
11590            needSep = true;
11591            printedAnything = true;
11592            pw.println("  Processes that are on old until the system is ready:");
11593            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11594                    "OnHold Norm", "OnHold PERS", dumpPackage);
11595        }
11596
11597        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11598
11599        if (mProcessCrashTimes.getMap().size() > 0) {
11600            boolean printed = false;
11601            long now = SystemClock.uptimeMillis();
11602            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11603            final int NP = pmap.size();
11604            for (int ip=0; ip<NP; ip++) {
11605                String pname = pmap.keyAt(ip);
11606                SparseArray<Long> uids = pmap.valueAt(ip);
11607                final int N = uids.size();
11608                for (int i=0; i<N; i++) {
11609                    int puid = uids.keyAt(i);
11610                    ProcessRecord r = mProcessNames.get(pname, puid);
11611                    if (dumpPackage != null && (r == null
11612                            || !r.pkgList.containsKey(dumpPackage))) {
11613                        continue;
11614                    }
11615                    if (!printed) {
11616                        if (needSep) pw.println();
11617                        needSep = true;
11618                        pw.println("  Time since processes crashed:");
11619                        printed = true;
11620                        printedAnything = true;
11621                    }
11622                    pw.print("    Process "); pw.print(pname);
11623                            pw.print(" uid "); pw.print(puid);
11624                            pw.print(": last crashed ");
11625                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11626                            pw.println(" ago");
11627                }
11628            }
11629        }
11630
11631        if (mBadProcesses.getMap().size() > 0) {
11632            boolean printed = false;
11633            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11634            final int NP = pmap.size();
11635            for (int ip=0; ip<NP; ip++) {
11636                String pname = pmap.keyAt(ip);
11637                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11638                final int N = uids.size();
11639                for (int i=0; i<N; i++) {
11640                    int puid = uids.keyAt(i);
11641                    ProcessRecord r = mProcessNames.get(pname, puid);
11642                    if (dumpPackage != null && (r == null
11643                            || !r.pkgList.containsKey(dumpPackage))) {
11644                        continue;
11645                    }
11646                    if (!printed) {
11647                        if (needSep) pw.println();
11648                        needSep = true;
11649                        pw.println("  Bad processes:");
11650                        printedAnything = true;
11651                    }
11652                    BadProcessInfo info = uids.valueAt(i);
11653                    pw.print("    Bad process "); pw.print(pname);
11654                            pw.print(" uid "); pw.print(puid);
11655                            pw.print(": crashed at time "); pw.println(info.time);
11656                    if (info.shortMsg != null) {
11657                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11658                    }
11659                    if (info.longMsg != null) {
11660                        pw.print("      Long msg: "); pw.println(info.longMsg);
11661                    }
11662                    if (info.stack != null) {
11663                        pw.println("      Stack:");
11664                        int lastPos = 0;
11665                        for (int pos=0; pos<info.stack.length(); pos++) {
11666                            if (info.stack.charAt(pos) == '\n') {
11667                                pw.print("        ");
11668                                pw.write(info.stack, lastPos, pos-lastPos);
11669                                pw.println();
11670                                lastPos = pos+1;
11671                            }
11672                        }
11673                        if (lastPos < info.stack.length()) {
11674                            pw.print("        ");
11675                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11676                            pw.println();
11677                        }
11678                    }
11679                }
11680            }
11681        }
11682
11683        if (dumpPackage == null) {
11684            pw.println();
11685            needSep = false;
11686            pw.println("  mStartedUsers:");
11687            for (int i=0; i<mStartedUsers.size(); i++) {
11688                UserStartedState uss = mStartedUsers.valueAt(i);
11689                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11690                        pw.print(": "); uss.dump("", pw);
11691            }
11692            pw.print("  mStartedUserArray: [");
11693            for (int i=0; i<mStartedUserArray.length; i++) {
11694                if (i > 0) pw.print(", ");
11695                pw.print(mStartedUserArray[i]);
11696            }
11697            pw.println("]");
11698            pw.print("  mUserLru: [");
11699            for (int i=0; i<mUserLru.size(); i++) {
11700                if (i > 0) pw.print(", ");
11701                pw.print(mUserLru.get(i));
11702            }
11703            pw.println("]");
11704            if (dumpAll) {
11705                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11706            }
11707            synchronized (mUserProfileGroupIdsSelfLocked) {
11708                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11709                    pw.println("  mUserProfileGroupIds:");
11710                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11711                        pw.print("    User #");
11712                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11713                        pw.print(" -> profile #");
11714                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11715                    }
11716                }
11717            }
11718        }
11719        if (mHomeProcess != null && (dumpPackage == null
11720                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11721            if (needSep) {
11722                pw.println();
11723                needSep = false;
11724            }
11725            pw.println("  mHomeProcess: " + mHomeProcess);
11726        }
11727        if (mPreviousProcess != null && (dumpPackage == null
11728                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11729            if (needSep) {
11730                pw.println();
11731                needSep = false;
11732            }
11733            pw.println("  mPreviousProcess: " + mPreviousProcess);
11734        }
11735        if (dumpAll) {
11736            StringBuilder sb = new StringBuilder(128);
11737            sb.append("  mPreviousProcessVisibleTime: ");
11738            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11739            pw.println(sb);
11740        }
11741        if (mHeavyWeightProcess != null && (dumpPackage == null
11742                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11743            if (needSep) {
11744                pw.println();
11745                needSep = false;
11746            }
11747            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11748        }
11749        if (dumpPackage == null) {
11750            pw.println("  mConfiguration: " + mConfiguration);
11751        }
11752        if (dumpAll) {
11753            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11754            if (mCompatModePackages.getPackages().size() > 0) {
11755                boolean printed = false;
11756                for (Map.Entry<String, Integer> entry
11757                        : mCompatModePackages.getPackages().entrySet()) {
11758                    String pkg = entry.getKey();
11759                    int mode = entry.getValue();
11760                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11761                        continue;
11762                    }
11763                    if (!printed) {
11764                        pw.println("  mScreenCompatPackages:");
11765                        printed = true;
11766                    }
11767                    pw.print("    "); pw.print(pkg); pw.print(": ");
11768                            pw.print(mode); pw.println();
11769                }
11770            }
11771        }
11772        if (dumpPackage == null) {
11773            if (mSleeping || mWentToSleep || mLockScreenShown) {
11774                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11775                        + " mLockScreenShown " + mLockScreenShown);
11776            }
11777            if (mShuttingDown || mRunningVoice) {
11778                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11779            }
11780        }
11781        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11782                || mOrigWaitForDebugger) {
11783            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11784                    || dumpPackage.equals(mOrigDebugApp)) {
11785                if (needSep) {
11786                    pw.println();
11787                    needSep = false;
11788                }
11789                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11790                        + " mDebugTransient=" + mDebugTransient
11791                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11792            }
11793        }
11794        if (mOpenGlTraceApp != null) {
11795            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11796                if (needSep) {
11797                    pw.println();
11798                    needSep = false;
11799                }
11800                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11801            }
11802        }
11803        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11804                || mProfileFd != null) {
11805            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11806                if (needSep) {
11807                    pw.println();
11808                    needSep = false;
11809                }
11810                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11811                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11812                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11813                        + mAutoStopProfiler);
11814            }
11815        }
11816        if (dumpPackage == null) {
11817            if (mAlwaysFinishActivities || mController != null) {
11818                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11819                        + " mController=" + mController);
11820            }
11821            if (dumpAll) {
11822                pw.println("  Total persistent processes: " + numPers);
11823                pw.println("  mProcessesReady=" + mProcessesReady
11824                        + " mSystemReady=" + mSystemReady);
11825                pw.println("  mBooting=" + mBooting
11826                        + " mBooted=" + mBooted
11827                        + " mFactoryTest=" + mFactoryTest);
11828                pw.print("  mLastPowerCheckRealtime=");
11829                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11830                        pw.println("");
11831                pw.print("  mLastPowerCheckUptime=");
11832                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11833                        pw.println("");
11834                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11835                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11836                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11837                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11838                        + " (" + mLruProcesses.size() + " total)"
11839                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11840                        + " mNumServiceProcs=" + mNumServiceProcs
11841                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11842                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11843                        + " mLastMemoryLevel" + mLastMemoryLevel
11844                        + " mLastNumProcesses" + mLastNumProcesses);
11845                long now = SystemClock.uptimeMillis();
11846                pw.print("  mLastIdleTime=");
11847                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11848                        pw.print(" mLowRamSinceLastIdle=");
11849                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11850                        pw.println();
11851            }
11852        }
11853
11854        if (!printedAnything) {
11855            pw.println("  (nothing)");
11856        }
11857    }
11858
11859    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11860            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11861        if (mProcessesToGc.size() > 0) {
11862            boolean printed = false;
11863            long now = SystemClock.uptimeMillis();
11864            for (int i=0; i<mProcessesToGc.size(); i++) {
11865                ProcessRecord proc = mProcessesToGc.get(i);
11866                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11867                    continue;
11868                }
11869                if (!printed) {
11870                    if (needSep) pw.println();
11871                    needSep = true;
11872                    pw.println("  Processes that are waiting to GC:");
11873                    printed = true;
11874                }
11875                pw.print("    Process "); pw.println(proc);
11876                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11877                        pw.print(", last gced=");
11878                        pw.print(now-proc.lastRequestedGc);
11879                        pw.print(" ms ago, last lowMem=");
11880                        pw.print(now-proc.lastLowMemory);
11881                        pw.println(" ms ago");
11882
11883            }
11884        }
11885        return needSep;
11886    }
11887
11888    void printOomLevel(PrintWriter pw, String name, int adj) {
11889        pw.print("    ");
11890        if (adj >= 0) {
11891            pw.print(' ');
11892            if (adj < 10) pw.print(' ');
11893        } else {
11894            if (adj > -10) pw.print(' ');
11895        }
11896        pw.print(adj);
11897        pw.print(": ");
11898        pw.print(name);
11899        pw.print(" (");
11900        pw.print(mProcessList.getMemLevel(adj)/1024);
11901        pw.println(" kB)");
11902    }
11903
11904    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11905            int opti, boolean dumpAll) {
11906        boolean needSep = false;
11907
11908        if (mLruProcesses.size() > 0) {
11909            if (needSep) pw.println();
11910            needSep = true;
11911            pw.println("  OOM levels:");
11912            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11913            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11914            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11915            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11916            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11917            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11918            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11919            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11920            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11921            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11922            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11923            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11924            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11925
11926            if (needSep) pw.println();
11927            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11928                    pw.print(" total, non-act at ");
11929                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11930                    pw.print(", non-svc at ");
11931                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11932                    pw.println("):");
11933            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11934            needSep = true;
11935        }
11936
11937        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11938
11939        pw.println();
11940        pw.println("  mHomeProcess: " + mHomeProcess);
11941        pw.println("  mPreviousProcess: " + mPreviousProcess);
11942        if (mHeavyWeightProcess != null) {
11943            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11944        }
11945
11946        return true;
11947    }
11948
11949    /**
11950     * There are three ways to call this:
11951     *  - no provider specified: dump all the providers
11952     *  - a flattened component name that matched an existing provider was specified as the
11953     *    first arg: dump that one provider
11954     *  - the first arg isn't the flattened component name of an existing provider:
11955     *    dump all providers whose component contains the first arg as a substring
11956     */
11957    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11958            int opti, boolean dumpAll) {
11959        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11960    }
11961
11962    static class ItemMatcher {
11963        ArrayList<ComponentName> components;
11964        ArrayList<String> strings;
11965        ArrayList<Integer> objects;
11966        boolean all;
11967
11968        ItemMatcher() {
11969            all = true;
11970        }
11971
11972        void build(String name) {
11973            ComponentName componentName = ComponentName.unflattenFromString(name);
11974            if (componentName != null) {
11975                if (components == null) {
11976                    components = new ArrayList<ComponentName>();
11977                }
11978                components.add(componentName);
11979                all = false;
11980            } else {
11981                int objectId = 0;
11982                // Not a '/' separated full component name; maybe an object ID?
11983                try {
11984                    objectId = Integer.parseInt(name, 16);
11985                    if (objects == null) {
11986                        objects = new ArrayList<Integer>();
11987                    }
11988                    objects.add(objectId);
11989                    all = false;
11990                } catch (RuntimeException e) {
11991                    // Not an integer; just do string match.
11992                    if (strings == null) {
11993                        strings = new ArrayList<String>();
11994                    }
11995                    strings.add(name);
11996                    all = false;
11997                }
11998            }
11999        }
12000
12001        int build(String[] args, int opti) {
12002            for (; opti<args.length; opti++) {
12003                String name = args[opti];
12004                if ("--".equals(name)) {
12005                    return opti+1;
12006                }
12007                build(name);
12008            }
12009            return opti;
12010        }
12011
12012        boolean match(Object object, ComponentName comp) {
12013            if (all) {
12014                return true;
12015            }
12016            if (components != null) {
12017                for (int i=0; i<components.size(); i++) {
12018                    if (components.get(i).equals(comp)) {
12019                        return true;
12020                    }
12021                }
12022            }
12023            if (objects != null) {
12024                for (int i=0; i<objects.size(); i++) {
12025                    if (System.identityHashCode(object) == objects.get(i)) {
12026                        return true;
12027                    }
12028                }
12029            }
12030            if (strings != null) {
12031                String flat = comp.flattenToString();
12032                for (int i=0; i<strings.size(); i++) {
12033                    if (flat.contains(strings.get(i))) {
12034                        return true;
12035                    }
12036                }
12037            }
12038            return false;
12039        }
12040    }
12041
12042    /**
12043     * There are three things that cmd can be:
12044     *  - a flattened component name that matches an existing activity
12045     *  - the cmd arg isn't the flattened component name of an existing activity:
12046     *    dump all activity whose component contains the cmd as a substring
12047     *  - A hex number of the ActivityRecord object instance.
12048     */
12049    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12050            int opti, boolean dumpAll) {
12051        ArrayList<ActivityRecord> activities;
12052
12053        synchronized (this) {
12054            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12055        }
12056
12057        if (activities.size() <= 0) {
12058            return false;
12059        }
12060
12061        String[] newArgs = new String[args.length - opti];
12062        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12063
12064        TaskRecord lastTask = null;
12065        boolean needSep = false;
12066        for (int i=activities.size()-1; i>=0; i--) {
12067            ActivityRecord r = activities.get(i);
12068            if (needSep) {
12069                pw.println();
12070            }
12071            needSep = true;
12072            synchronized (this) {
12073                if (lastTask != r.task) {
12074                    lastTask = r.task;
12075                    pw.print("TASK "); pw.print(lastTask.affinity);
12076                            pw.print(" id="); pw.println(lastTask.taskId);
12077                    if (dumpAll) {
12078                        lastTask.dump(pw, "  ");
12079                    }
12080                }
12081            }
12082            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12083        }
12084        return true;
12085    }
12086
12087    /**
12088     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12089     * there is a thread associated with the activity.
12090     */
12091    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12092            final ActivityRecord r, String[] args, boolean dumpAll) {
12093        String innerPrefix = prefix + "  ";
12094        synchronized (this) {
12095            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12096                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12097                    pw.print(" pid=");
12098                    if (r.app != null) pw.println(r.app.pid);
12099                    else pw.println("(not running)");
12100            if (dumpAll) {
12101                r.dump(pw, innerPrefix);
12102            }
12103        }
12104        if (r.app != null && r.app.thread != null) {
12105            // flush anything that is already in the PrintWriter since the thread is going
12106            // to write to the file descriptor directly
12107            pw.flush();
12108            try {
12109                TransferPipe tp = new TransferPipe();
12110                try {
12111                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12112                            r.appToken, innerPrefix, args);
12113                    tp.go(fd);
12114                } finally {
12115                    tp.kill();
12116                }
12117            } catch (IOException e) {
12118                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12119            } catch (RemoteException e) {
12120                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12121            }
12122        }
12123    }
12124
12125    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12126            int opti, boolean dumpAll, String dumpPackage) {
12127        boolean needSep = false;
12128        boolean onlyHistory = false;
12129        boolean printedAnything = false;
12130
12131        if ("history".equals(dumpPackage)) {
12132            if (opti < args.length && "-s".equals(args[opti])) {
12133                dumpAll = false;
12134            }
12135            onlyHistory = true;
12136            dumpPackage = null;
12137        }
12138
12139        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12140        if (!onlyHistory && dumpAll) {
12141            if (mRegisteredReceivers.size() > 0) {
12142                boolean printed = false;
12143                Iterator it = mRegisteredReceivers.values().iterator();
12144                while (it.hasNext()) {
12145                    ReceiverList r = (ReceiverList)it.next();
12146                    if (dumpPackage != null && (r.app == null ||
12147                            !dumpPackage.equals(r.app.info.packageName))) {
12148                        continue;
12149                    }
12150                    if (!printed) {
12151                        pw.println("  Registered Receivers:");
12152                        needSep = true;
12153                        printed = true;
12154                        printedAnything = true;
12155                    }
12156                    pw.print("  * "); pw.println(r);
12157                    r.dump(pw, "    ");
12158                }
12159            }
12160
12161            if (mReceiverResolver.dump(pw, needSep ?
12162                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12163                    "    ", dumpPackage, false)) {
12164                needSep = true;
12165                printedAnything = true;
12166            }
12167        }
12168
12169        for (BroadcastQueue q : mBroadcastQueues) {
12170            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12171            printedAnything |= needSep;
12172        }
12173
12174        needSep = true;
12175
12176        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12177            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12178                if (needSep) {
12179                    pw.println();
12180                }
12181                needSep = true;
12182                printedAnything = true;
12183                pw.print("  Sticky broadcasts for user ");
12184                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12185                StringBuilder sb = new StringBuilder(128);
12186                for (Map.Entry<String, ArrayList<Intent>> ent
12187                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12188                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12189                    if (dumpAll) {
12190                        pw.println(":");
12191                        ArrayList<Intent> intents = ent.getValue();
12192                        final int N = intents.size();
12193                        for (int i=0; i<N; i++) {
12194                            sb.setLength(0);
12195                            sb.append("    Intent: ");
12196                            intents.get(i).toShortString(sb, false, true, false, false);
12197                            pw.println(sb.toString());
12198                            Bundle bundle = intents.get(i).getExtras();
12199                            if (bundle != null) {
12200                                pw.print("      ");
12201                                pw.println(bundle.toString());
12202                            }
12203                        }
12204                    } else {
12205                        pw.println("");
12206                    }
12207                }
12208            }
12209        }
12210
12211        if (!onlyHistory && dumpAll) {
12212            pw.println();
12213            for (BroadcastQueue queue : mBroadcastQueues) {
12214                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12215                        + queue.mBroadcastsScheduled);
12216            }
12217            pw.println("  mHandler:");
12218            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12219            needSep = true;
12220            printedAnything = true;
12221        }
12222
12223        if (!printedAnything) {
12224            pw.println("  (nothing)");
12225        }
12226    }
12227
12228    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12229            int opti, boolean dumpAll, String dumpPackage) {
12230        boolean needSep;
12231        boolean printedAnything = false;
12232
12233        ItemMatcher matcher = new ItemMatcher();
12234        matcher.build(args, opti);
12235
12236        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12237
12238        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12239        printedAnything |= needSep;
12240
12241        if (mLaunchingProviders.size() > 0) {
12242            boolean printed = false;
12243            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12244                ContentProviderRecord r = mLaunchingProviders.get(i);
12245                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12246                    continue;
12247                }
12248                if (!printed) {
12249                    if (needSep) pw.println();
12250                    needSep = true;
12251                    pw.println("  Launching content providers:");
12252                    printed = true;
12253                    printedAnything = true;
12254                }
12255                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12256                        pw.println(r);
12257            }
12258        }
12259
12260        if (mGrantedUriPermissions.size() > 0) {
12261            boolean printed = false;
12262            int dumpUid = -2;
12263            if (dumpPackage != null) {
12264                try {
12265                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12266                } catch (NameNotFoundException e) {
12267                    dumpUid = -1;
12268                }
12269            }
12270            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12271                int uid = mGrantedUriPermissions.keyAt(i);
12272                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12273                    continue;
12274                }
12275                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12276                if (!printed) {
12277                    if (needSep) pw.println();
12278                    needSep = true;
12279                    pw.println("  Granted Uri Permissions:");
12280                    printed = true;
12281                    printedAnything = true;
12282                }
12283                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12284                for (UriPermission perm : perms.values()) {
12285                    pw.print("    "); pw.println(perm);
12286                    if (dumpAll) {
12287                        perm.dump(pw, "      ");
12288                    }
12289                }
12290            }
12291        }
12292
12293        if (!printedAnything) {
12294            pw.println("  (nothing)");
12295        }
12296    }
12297
12298    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12299            int opti, boolean dumpAll, String dumpPackage) {
12300        boolean printed = false;
12301
12302        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12303
12304        if (mIntentSenderRecords.size() > 0) {
12305            Iterator<WeakReference<PendingIntentRecord>> it
12306                    = mIntentSenderRecords.values().iterator();
12307            while (it.hasNext()) {
12308                WeakReference<PendingIntentRecord> ref = it.next();
12309                PendingIntentRecord rec = ref != null ? ref.get(): null;
12310                if (dumpPackage != null && (rec == null
12311                        || !dumpPackage.equals(rec.key.packageName))) {
12312                    continue;
12313                }
12314                printed = true;
12315                if (rec != null) {
12316                    pw.print("  * "); pw.println(rec);
12317                    if (dumpAll) {
12318                        rec.dump(pw, "    ");
12319                    }
12320                } else {
12321                    pw.print("  * "); pw.println(ref);
12322                }
12323            }
12324        }
12325
12326        if (!printed) {
12327            pw.println("  (nothing)");
12328        }
12329    }
12330
12331    private static final int dumpProcessList(PrintWriter pw,
12332            ActivityManagerService service, List list,
12333            String prefix, String normalLabel, String persistentLabel,
12334            String dumpPackage) {
12335        int numPers = 0;
12336        final int N = list.size()-1;
12337        for (int i=N; i>=0; i--) {
12338            ProcessRecord r = (ProcessRecord)list.get(i);
12339            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12340                continue;
12341            }
12342            pw.println(String.format("%s%s #%2d: %s",
12343                    prefix, (r.persistent ? persistentLabel : normalLabel),
12344                    i, r.toString()));
12345            if (r.persistent) {
12346                numPers++;
12347            }
12348        }
12349        return numPers;
12350    }
12351
12352    private static final boolean dumpProcessOomList(PrintWriter pw,
12353            ActivityManagerService service, List<ProcessRecord> origList,
12354            String prefix, String normalLabel, String persistentLabel,
12355            boolean inclDetails, String dumpPackage) {
12356
12357        ArrayList<Pair<ProcessRecord, Integer>> list
12358                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12359        for (int i=0; i<origList.size(); i++) {
12360            ProcessRecord r = origList.get(i);
12361            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12362                continue;
12363            }
12364            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12365        }
12366
12367        if (list.size() <= 0) {
12368            return false;
12369        }
12370
12371        Comparator<Pair<ProcessRecord, Integer>> comparator
12372                = new Comparator<Pair<ProcessRecord, Integer>>() {
12373            @Override
12374            public int compare(Pair<ProcessRecord, Integer> object1,
12375                    Pair<ProcessRecord, Integer> object2) {
12376                if (object1.first.setAdj != object2.first.setAdj) {
12377                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12378                }
12379                if (object1.second.intValue() != object2.second.intValue()) {
12380                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12381                }
12382                return 0;
12383            }
12384        };
12385
12386        Collections.sort(list, comparator);
12387
12388        final long curRealtime = SystemClock.elapsedRealtime();
12389        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12390        final long curUptime = SystemClock.uptimeMillis();
12391        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12392
12393        for (int i=list.size()-1; i>=0; i--) {
12394            ProcessRecord r = list.get(i).first;
12395            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12396            char schedGroup;
12397            switch (r.setSchedGroup) {
12398                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12399                    schedGroup = 'B';
12400                    break;
12401                case Process.THREAD_GROUP_DEFAULT:
12402                    schedGroup = 'F';
12403                    break;
12404                default:
12405                    schedGroup = '?';
12406                    break;
12407            }
12408            char foreground;
12409            if (r.foregroundActivities) {
12410                foreground = 'A';
12411            } else if (r.foregroundServices) {
12412                foreground = 'S';
12413            } else {
12414                foreground = ' ';
12415            }
12416            String procState = ProcessList.makeProcStateString(r.curProcState);
12417            pw.print(prefix);
12418            pw.print(r.persistent ? persistentLabel : normalLabel);
12419            pw.print(" #");
12420            int num = (origList.size()-1)-list.get(i).second;
12421            if (num < 10) pw.print(' ');
12422            pw.print(num);
12423            pw.print(": ");
12424            pw.print(oomAdj);
12425            pw.print(' ');
12426            pw.print(schedGroup);
12427            pw.print('/');
12428            pw.print(foreground);
12429            pw.print('/');
12430            pw.print(procState);
12431            pw.print(" trm:");
12432            if (r.trimMemoryLevel < 10) pw.print(' ');
12433            pw.print(r.trimMemoryLevel);
12434            pw.print(' ');
12435            pw.print(r.toShortString());
12436            pw.print(" (");
12437            pw.print(r.adjType);
12438            pw.println(')');
12439            if (r.adjSource != null || r.adjTarget != null) {
12440                pw.print(prefix);
12441                pw.print("    ");
12442                if (r.adjTarget instanceof ComponentName) {
12443                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12444                } else if (r.adjTarget != null) {
12445                    pw.print(r.adjTarget.toString());
12446                } else {
12447                    pw.print("{null}");
12448                }
12449                pw.print("<=");
12450                if (r.adjSource instanceof ProcessRecord) {
12451                    pw.print("Proc{");
12452                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12453                    pw.println("}");
12454                } else if (r.adjSource != null) {
12455                    pw.println(r.adjSource.toString());
12456                } else {
12457                    pw.println("{null}");
12458                }
12459            }
12460            if (inclDetails) {
12461                pw.print(prefix);
12462                pw.print("    ");
12463                pw.print("oom: max="); pw.print(r.maxAdj);
12464                pw.print(" curRaw="); pw.print(r.curRawAdj);
12465                pw.print(" setRaw="); pw.print(r.setRawAdj);
12466                pw.print(" cur="); pw.print(r.curAdj);
12467                pw.print(" set="); pw.println(r.setAdj);
12468                pw.print(prefix);
12469                pw.print("    ");
12470                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12471                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12472                pw.print(" lastPss="); pw.print(r.lastPss);
12473                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12474                pw.print(prefix);
12475                pw.print("    ");
12476                pw.print("cached="); pw.print(r.cached);
12477                pw.print(" empty="); pw.print(r.empty);
12478                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12479
12480                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12481                    if (r.lastWakeTime != 0) {
12482                        long wtime;
12483                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12484                        synchronized (stats) {
12485                            wtime = stats.getProcessWakeTime(r.info.uid,
12486                                    r.pid, curRealtime);
12487                        }
12488                        long timeUsed = wtime - r.lastWakeTime;
12489                        pw.print(prefix);
12490                        pw.print("    ");
12491                        pw.print("keep awake over ");
12492                        TimeUtils.formatDuration(realtimeSince, pw);
12493                        pw.print(" used ");
12494                        TimeUtils.formatDuration(timeUsed, pw);
12495                        pw.print(" (");
12496                        pw.print((timeUsed*100)/realtimeSince);
12497                        pw.println("%)");
12498                    }
12499                    if (r.lastCpuTime != 0) {
12500                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12501                        pw.print(prefix);
12502                        pw.print("    ");
12503                        pw.print("run cpu over ");
12504                        TimeUtils.formatDuration(uptimeSince, pw);
12505                        pw.print(" used ");
12506                        TimeUtils.formatDuration(timeUsed, pw);
12507                        pw.print(" (");
12508                        pw.print((timeUsed*100)/uptimeSince);
12509                        pw.println("%)");
12510                    }
12511                }
12512            }
12513        }
12514        return true;
12515    }
12516
12517    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12518        ArrayList<ProcessRecord> procs;
12519        synchronized (this) {
12520            if (args != null && args.length > start
12521                    && args[start].charAt(0) != '-') {
12522                procs = new ArrayList<ProcessRecord>();
12523                int pid = -1;
12524                try {
12525                    pid = Integer.parseInt(args[start]);
12526                } catch (NumberFormatException e) {
12527                }
12528                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12529                    ProcessRecord proc = mLruProcesses.get(i);
12530                    if (proc.pid == pid) {
12531                        procs.add(proc);
12532                    } else if (proc.processName.equals(args[start])) {
12533                        procs.add(proc);
12534                    }
12535                }
12536                if (procs.size() <= 0) {
12537                    return null;
12538                }
12539            } else {
12540                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12541            }
12542        }
12543        return procs;
12544    }
12545
12546    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12547            PrintWriter pw, String[] args) {
12548        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12549        if (procs == null) {
12550            pw.println("No process found for: " + args[0]);
12551            return;
12552        }
12553
12554        long uptime = SystemClock.uptimeMillis();
12555        long realtime = SystemClock.elapsedRealtime();
12556        pw.println("Applications Graphics Acceleration Info:");
12557        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12558
12559        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12560            ProcessRecord r = procs.get(i);
12561            if (r.thread != null) {
12562                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12563                pw.flush();
12564                try {
12565                    TransferPipe tp = new TransferPipe();
12566                    try {
12567                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12568                        tp.go(fd);
12569                    } finally {
12570                        tp.kill();
12571                    }
12572                } catch (IOException e) {
12573                    pw.println("Failure while dumping the app: " + r);
12574                    pw.flush();
12575                } catch (RemoteException e) {
12576                    pw.println("Got a RemoteException while dumping the app " + r);
12577                    pw.flush();
12578                }
12579            }
12580        }
12581    }
12582
12583    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12584        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12585        if (procs == null) {
12586            pw.println("No process found for: " + args[0]);
12587            return;
12588        }
12589
12590        pw.println("Applications Database Info:");
12591
12592        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12593            ProcessRecord r = procs.get(i);
12594            if (r.thread != null) {
12595                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12596                pw.flush();
12597                try {
12598                    TransferPipe tp = new TransferPipe();
12599                    try {
12600                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12601                        tp.go(fd);
12602                    } finally {
12603                        tp.kill();
12604                    }
12605                } catch (IOException e) {
12606                    pw.println("Failure while dumping the app: " + r);
12607                    pw.flush();
12608                } catch (RemoteException e) {
12609                    pw.println("Got a RemoteException while dumping the app " + r);
12610                    pw.flush();
12611                }
12612            }
12613        }
12614    }
12615
12616    final static class MemItem {
12617        final boolean isProc;
12618        final String label;
12619        final String shortLabel;
12620        final long pss;
12621        final int id;
12622        final boolean hasActivities;
12623        ArrayList<MemItem> subitems;
12624
12625        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12626                boolean _hasActivities) {
12627            isProc = true;
12628            label = _label;
12629            shortLabel = _shortLabel;
12630            pss = _pss;
12631            id = _id;
12632            hasActivities = _hasActivities;
12633        }
12634
12635        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12636            isProc = false;
12637            label = _label;
12638            shortLabel = _shortLabel;
12639            pss = _pss;
12640            id = _id;
12641            hasActivities = false;
12642        }
12643    }
12644
12645    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12646            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12647        if (sort && !isCompact) {
12648            Collections.sort(items, new Comparator<MemItem>() {
12649                @Override
12650                public int compare(MemItem lhs, MemItem rhs) {
12651                    if (lhs.pss < rhs.pss) {
12652                        return 1;
12653                    } else if (lhs.pss > rhs.pss) {
12654                        return -1;
12655                    }
12656                    return 0;
12657                }
12658            });
12659        }
12660
12661        for (int i=0; i<items.size(); i++) {
12662            MemItem mi = items.get(i);
12663            if (!isCompact) {
12664                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12665            } else if (mi.isProc) {
12666                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12667                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12668                pw.println(mi.hasActivities ? ",a" : ",e");
12669            } else {
12670                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12671                pw.println(mi.pss);
12672            }
12673            if (mi.subitems != null) {
12674                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12675                        true, isCompact);
12676            }
12677        }
12678    }
12679
12680    // These are in KB.
12681    static final long[] DUMP_MEM_BUCKETS = new long[] {
12682        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12683        120*1024, 160*1024, 200*1024,
12684        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12685        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12686    };
12687
12688    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12689            boolean stackLike) {
12690        int start = label.lastIndexOf('.');
12691        if (start >= 0) start++;
12692        else start = 0;
12693        int end = label.length();
12694        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12695            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12696                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12697                out.append(bucket);
12698                out.append(stackLike ? "MB." : "MB ");
12699                out.append(label, start, end);
12700                return;
12701            }
12702        }
12703        out.append(memKB/1024);
12704        out.append(stackLike ? "MB." : "MB ");
12705        out.append(label, start, end);
12706    }
12707
12708    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12709            ProcessList.NATIVE_ADJ,
12710            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12711            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12712            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12713            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12714            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12715    };
12716    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12717            "Native",
12718            "System", "Persistent", "Foreground",
12719            "Visible", "Perceptible",
12720            "Heavy Weight", "Backup",
12721            "A Services", "Home",
12722            "Previous", "B Services", "Cached"
12723    };
12724    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12725            "native",
12726            "sys", "pers", "fore",
12727            "vis", "percept",
12728            "heavy", "backup",
12729            "servicea", "home",
12730            "prev", "serviceb", "cached"
12731    };
12732
12733    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12734            long realtime, boolean isCheckinRequest, boolean isCompact) {
12735        if (isCheckinRequest || isCompact) {
12736            // short checkin version
12737            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12738        } else {
12739            pw.println("Applications Memory Usage (kB):");
12740            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12741        }
12742    }
12743
12744    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12745            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12746        boolean dumpDetails = false;
12747        boolean dumpFullDetails = false;
12748        boolean dumpDalvik = false;
12749        boolean oomOnly = false;
12750        boolean isCompact = false;
12751        boolean localOnly = false;
12752
12753        int opti = 0;
12754        while (opti < args.length) {
12755            String opt = args[opti];
12756            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12757                break;
12758            }
12759            opti++;
12760            if ("-a".equals(opt)) {
12761                dumpDetails = true;
12762                dumpFullDetails = true;
12763                dumpDalvik = true;
12764            } else if ("-d".equals(opt)) {
12765                dumpDalvik = true;
12766            } else if ("-c".equals(opt)) {
12767                isCompact = true;
12768            } else if ("--oom".equals(opt)) {
12769                oomOnly = true;
12770            } else if ("--local".equals(opt)) {
12771                localOnly = true;
12772            } else if ("-h".equals(opt)) {
12773                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12774                pw.println("  -a: include all available information for each process.");
12775                pw.println("  -d: include dalvik details when dumping process details.");
12776                pw.println("  -c: dump in a compact machine-parseable representation.");
12777                pw.println("  --oom: only show processes organized by oom adj.");
12778                pw.println("  --local: only collect details locally, don't call process.");
12779                pw.println("If [process] is specified it can be the name or ");
12780                pw.println("pid of a specific process to dump.");
12781                return;
12782            } else {
12783                pw.println("Unknown argument: " + opt + "; use -h for help");
12784            }
12785        }
12786
12787        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12788        long uptime = SystemClock.uptimeMillis();
12789        long realtime = SystemClock.elapsedRealtime();
12790        final long[] tmpLong = new long[1];
12791
12792        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12793        if (procs == null) {
12794            // No Java processes.  Maybe they want to print a native process.
12795            if (args != null && args.length > opti
12796                    && args[opti].charAt(0) != '-') {
12797                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12798                        = new ArrayList<ProcessCpuTracker.Stats>();
12799                updateCpuStatsNow();
12800                int findPid = -1;
12801                try {
12802                    findPid = Integer.parseInt(args[opti]);
12803                } catch (NumberFormatException e) {
12804                }
12805                synchronized (mProcessCpuThread) {
12806                    final int N = mProcessCpuTracker.countStats();
12807                    for (int i=0; i<N; i++) {
12808                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12809                        if (st.pid == findPid || (st.baseName != null
12810                                && st.baseName.equals(args[opti]))) {
12811                            nativeProcs.add(st);
12812                        }
12813                    }
12814                }
12815                if (nativeProcs.size() > 0) {
12816                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12817                            isCompact);
12818                    Debug.MemoryInfo mi = null;
12819                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12820                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12821                        final int pid = r.pid;
12822                        if (!isCheckinRequest && dumpDetails) {
12823                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12824                        }
12825                        if (mi == null) {
12826                            mi = new Debug.MemoryInfo();
12827                        }
12828                        if (dumpDetails || (!brief && !oomOnly)) {
12829                            Debug.getMemoryInfo(pid, mi);
12830                        } else {
12831                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12832                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12833                        }
12834                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12835                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12836                        if (isCheckinRequest) {
12837                            pw.println();
12838                        }
12839                    }
12840                    return;
12841                }
12842            }
12843            pw.println("No process found for: " + args[opti]);
12844            return;
12845        }
12846
12847        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12848            dumpDetails = true;
12849        }
12850
12851        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12852
12853        String[] innerArgs = new String[args.length-opti];
12854        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12855
12856        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12857        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12858        long nativePss=0, dalvikPss=0, otherPss=0;
12859        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12860
12861        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12862        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12863                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12864
12865        long totalPss = 0;
12866        long cachedPss = 0;
12867
12868        Debug.MemoryInfo mi = null;
12869        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12870            final ProcessRecord r = procs.get(i);
12871            final IApplicationThread thread;
12872            final int pid;
12873            final int oomAdj;
12874            final boolean hasActivities;
12875            synchronized (this) {
12876                thread = r.thread;
12877                pid = r.pid;
12878                oomAdj = r.getSetAdjWithServices();
12879                hasActivities = r.activities.size() > 0;
12880            }
12881            if (thread != null) {
12882                if (!isCheckinRequest && dumpDetails) {
12883                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12884                }
12885                if (mi == null) {
12886                    mi = new Debug.MemoryInfo();
12887                }
12888                if (dumpDetails || (!brief && !oomOnly)) {
12889                    Debug.getMemoryInfo(pid, mi);
12890                } else {
12891                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12892                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12893                }
12894                if (dumpDetails) {
12895                    if (localOnly) {
12896                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12897                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12898                        if (isCheckinRequest) {
12899                            pw.println();
12900                        }
12901                    } else {
12902                        try {
12903                            pw.flush();
12904                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12905                                    dumpDalvik, innerArgs);
12906                        } catch (RemoteException e) {
12907                            if (!isCheckinRequest) {
12908                                pw.println("Got RemoteException!");
12909                                pw.flush();
12910                            }
12911                        }
12912                    }
12913                }
12914
12915                final long myTotalPss = mi.getTotalPss();
12916                final long myTotalUss = mi.getTotalUss();
12917
12918                synchronized (this) {
12919                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12920                        // Record this for posterity if the process has been stable.
12921                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12922                    }
12923                }
12924
12925                if (!isCheckinRequest && mi != null) {
12926                    totalPss += myTotalPss;
12927                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12928                            (hasActivities ? " / activities)" : ")"),
12929                            r.processName, myTotalPss, pid, hasActivities);
12930                    procMems.add(pssItem);
12931                    procMemsMap.put(pid, pssItem);
12932
12933                    nativePss += mi.nativePss;
12934                    dalvikPss += mi.dalvikPss;
12935                    otherPss += mi.otherPss;
12936                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12937                        long mem = mi.getOtherPss(j);
12938                        miscPss[j] += mem;
12939                        otherPss -= mem;
12940                    }
12941
12942                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12943                        cachedPss += myTotalPss;
12944                    }
12945
12946                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12947                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12948                                || oomIndex == (oomPss.length-1)) {
12949                            oomPss[oomIndex] += myTotalPss;
12950                            if (oomProcs[oomIndex] == null) {
12951                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12952                            }
12953                            oomProcs[oomIndex].add(pssItem);
12954                            break;
12955                        }
12956                    }
12957                }
12958            }
12959        }
12960
12961        long nativeProcTotalPss = 0;
12962
12963        if (!isCheckinRequest && procs.size() > 1) {
12964            // If we are showing aggregations, also look for native processes to
12965            // include so that our aggregations are more accurate.
12966            updateCpuStatsNow();
12967            synchronized (mProcessCpuThread) {
12968                final int N = mProcessCpuTracker.countStats();
12969                for (int i=0; i<N; i++) {
12970                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12971                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12972                        if (mi == null) {
12973                            mi = new Debug.MemoryInfo();
12974                        }
12975                        if (!brief && !oomOnly) {
12976                            Debug.getMemoryInfo(st.pid, mi);
12977                        } else {
12978                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12979                            mi.nativePrivateDirty = (int)tmpLong[0];
12980                        }
12981
12982                        final long myTotalPss = mi.getTotalPss();
12983                        totalPss += myTotalPss;
12984                        nativeProcTotalPss += myTotalPss;
12985
12986                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12987                                st.name, myTotalPss, st.pid, false);
12988                        procMems.add(pssItem);
12989
12990                        nativePss += mi.nativePss;
12991                        dalvikPss += mi.dalvikPss;
12992                        otherPss += mi.otherPss;
12993                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12994                            long mem = mi.getOtherPss(j);
12995                            miscPss[j] += mem;
12996                            otherPss -= mem;
12997                        }
12998                        oomPss[0] += myTotalPss;
12999                        if (oomProcs[0] == null) {
13000                            oomProcs[0] = new ArrayList<MemItem>();
13001                        }
13002                        oomProcs[0].add(pssItem);
13003                    }
13004                }
13005            }
13006
13007            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13008
13009            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13010            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13011            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13012            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13013                String label = Debug.MemoryInfo.getOtherLabel(j);
13014                catMems.add(new MemItem(label, label, miscPss[j], j));
13015            }
13016
13017            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13018            for (int j=0; j<oomPss.length; j++) {
13019                if (oomPss[j] != 0) {
13020                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13021                            : DUMP_MEM_OOM_LABEL[j];
13022                    MemItem item = new MemItem(label, label, oomPss[j],
13023                            DUMP_MEM_OOM_ADJ[j]);
13024                    item.subitems = oomProcs[j];
13025                    oomMems.add(item);
13026                }
13027            }
13028
13029            if (!brief && !oomOnly && !isCompact) {
13030                pw.println();
13031                pw.println("Total PSS by process:");
13032                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13033                pw.println();
13034            }
13035            if (!isCompact) {
13036                pw.println("Total PSS by OOM adjustment:");
13037            }
13038            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13039            if (!brief && !oomOnly) {
13040                PrintWriter out = categoryPw != null ? categoryPw : pw;
13041                if (!isCompact) {
13042                    out.println();
13043                    out.println("Total PSS by category:");
13044                }
13045                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13046            }
13047            if (!isCompact) {
13048                pw.println();
13049            }
13050            MemInfoReader memInfo = new MemInfoReader();
13051            memInfo.readMemInfo();
13052            if (nativeProcTotalPss > 0) {
13053                synchronized (this) {
13054                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13055                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13056                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13057                            nativeProcTotalPss);
13058                }
13059            }
13060            if (!brief) {
13061                if (!isCompact) {
13062                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13063                    pw.print(" kB (status ");
13064                    switch (mLastMemoryLevel) {
13065                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13066                            pw.println("normal)");
13067                            break;
13068                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13069                            pw.println("moderate)");
13070                            break;
13071                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13072                            pw.println("low)");
13073                            break;
13074                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13075                            pw.println("critical)");
13076                            break;
13077                        default:
13078                            pw.print(mLastMemoryLevel);
13079                            pw.println(")");
13080                            break;
13081                    }
13082                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13083                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13084                            pw.print(cachedPss); pw.print(" cached pss + ");
13085                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13086                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13087                } else {
13088                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13089                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13090                            + memInfo.getFreeSizeKb()); pw.print(",");
13091                    pw.println(totalPss - cachedPss);
13092                }
13093            }
13094            if (!isCompact) {
13095                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13096                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13097                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13098                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13099                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13100                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13101                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13102                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13103                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13104                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13105                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13106            }
13107            if (!brief) {
13108                if (memInfo.getZramTotalSizeKb() != 0) {
13109                    if (!isCompact) {
13110                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13111                                pw.print(" kB physical used for ");
13112                                pw.print(memInfo.getSwapTotalSizeKb()
13113                                        - memInfo.getSwapFreeSizeKb());
13114                                pw.print(" kB in swap (");
13115                                pw.print(memInfo.getSwapTotalSizeKb());
13116                                pw.println(" kB total swap)");
13117                    } else {
13118                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13119                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13120                                pw.println(memInfo.getSwapFreeSizeKb());
13121                    }
13122                }
13123                final int[] SINGLE_LONG_FORMAT = new int[] {
13124                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13125                };
13126                long[] longOut = new long[1];
13127                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13128                        SINGLE_LONG_FORMAT, null, longOut, null);
13129                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13130                longOut[0] = 0;
13131                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13132                        SINGLE_LONG_FORMAT, null, longOut, null);
13133                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13134                longOut[0] = 0;
13135                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13136                        SINGLE_LONG_FORMAT, null, longOut, null);
13137                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13138                longOut[0] = 0;
13139                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13140                        SINGLE_LONG_FORMAT, null, longOut, null);
13141                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13142                if (!isCompact) {
13143                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13144                        pw.print("      KSM: "); pw.print(sharing);
13145                                pw.print(" kB saved from shared ");
13146                                pw.print(shared); pw.println(" kB");
13147                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13148                                pw.print(voltile); pw.println(" kB volatile");
13149                    }
13150                    pw.print("   Tuning: ");
13151                    pw.print(ActivityManager.staticGetMemoryClass());
13152                    pw.print(" (large ");
13153                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13154                    pw.print("), oom ");
13155                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13156                    pw.print(" kB");
13157                    pw.print(", restore limit ");
13158                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13159                    pw.print(" kB");
13160                    if (ActivityManager.isLowRamDeviceStatic()) {
13161                        pw.print(" (low-ram)");
13162                    }
13163                    if (ActivityManager.isHighEndGfx()) {
13164                        pw.print(" (high-end-gfx)");
13165                    }
13166                    pw.println();
13167                } else {
13168                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13169                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13170                    pw.println(voltile);
13171                    pw.print("tuning,");
13172                    pw.print(ActivityManager.staticGetMemoryClass());
13173                    pw.print(',');
13174                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13175                    pw.print(',');
13176                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13177                    if (ActivityManager.isLowRamDeviceStatic()) {
13178                        pw.print(",low-ram");
13179                    }
13180                    if (ActivityManager.isHighEndGfx()) {
13181                        pw.print(",high-end-gfx");
13182                    }
13183                    pw.println();
13184                }
13185            }
13186        }
13187    }
13188
13189    /**
13190     * Searches array of arguments for the specified string
13191     * @param args array of argument strings
13192     * @param value value to search for
13193     * @return true if the value is contained in the array
13194     */
13195    private static boolean scanArgs(String[] args, String value) {
13196        if (args != null) {
13197            for (String arg : args) {
13198                if (value.equals(arg)) {
13199                    return true;
13200                }
13201            }
13202        }
13203        return false;
13204    }
13205
13206    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13207            ContentProviderRecord cpr, boolean always) {
13208        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13209
13210        if (!inLaunching || always) {
13211            synchronized (cpr) {
13212                cpr.launchingApp = null;
13213                cpr.notifyAll();
13214            }
13215            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13216            String names[] = cpr.info.authority.split(";");
13217            for (int j = 0; j < names.length; j++) {
13218                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13219            }
13220        }
13221
13222        for (int i=0; i<cpr.connections.size(); i++) {
13223            ContentProviderConnection conn = cpr.connections.get(i);
13224            if (conn.waiting) {
13225                // If this connection is waiting for the provider, then we don't
13226                // need to mess with its process unless we are always removing
13227                // or for some reason the provider is not currently launching.
13228                if (inLaunching && !always) {
13229                    continue;
13230                }
13231            }
13232            ProcessRecord capp = conn.client;
13233            conn.dead = true;
13234            if (conn.stableCount > 0) {
13235                if (!capp.persistent && capp.thread != null
13236                        && capp.pid != 0
13237                        && capp.pid != MY_PID) {
13238                    killUnneededProcessLocked(capp, "depends on provider "
13239                            + cpr.name.flattenToShortString()
13240                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13241                }
13242            } else if (capp.thread != null && conn.provider.provider != null) {
13243                try {
13244                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13245                } catch (RemoteException e) {
13246                }
13247                // In the protocol here, we don't expect the client to correctly
13248                // clean up this connection, we'll just remove it.
13249                cpr.connections.remove(i);
13250                conn.client.conProviders.remove(conn);
13251            }
13252        }
13253
13254        if (inLaunching && always) {
13255            mLaunchingProviders.remove(cpr);
13256        }
13257        return inLaunching;
13258    }
13259
13260    /**
13261     * Main code for cleaning up a process when it has gone away.  This is
13262     * called both as a result of the process dying, or directly when stopping
13263     * a process when running in single process mode.
13264     */
13265    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13266            boolean restarting, boolean allowRestart, int index) {
13267        if (index >= 0) {
13268            removeLruProcessLocked(app);
13269            ProcessList.remove(app.pid);
13270        }
13271
13272        mProcessesToGc.remove(app);
13273        mPendingPssProcesses.remove(app);
13274
13275        // Dismiss any open dialogs.
13276        if (app.crashDialog != null && !app.forceCrashReport) {
13277            app.crashDialog.dismiss();
13278            app.crashDialog = null;
13279        }
13280        if (app.anrDialog != null) {
13281            app.anrDialog.dismiss();
13282            app.anrDialog = null;
13283        }
13284        if (app.waitDialog != null) {
13285            app.waitDialog.dismiss();
13286            app.waitDialog = null;
13287        }
13288
13289        app.crashing = false;
13290        app.notResponding = false;
13291
13292        app.resetPackageList(mProcessStats);
13293        app.unlinkDeathRecipient();
13294        app.makeInactive(mProcessStats);
13295        app.waitingToKill = null;
13296        app.forcingToForeground = null;
13297        updateProcessForegroundLocked(app, false, false);
13298        app.foregroundActivities = false;
13299        app.hasShownUi = false;
13300        app.treatLikeActivity = false;
13301        app.hasAboveClient = false;
13302        app.hasClientActivities = false;
13303
13304        mServices.killServicesLocked(app, allowRestart);
13305
13306        boolean restart = false;
13307
13308        // Remove published content providers.
13309        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13310            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13311            final boolean always = app.bad || !allowRestart;
13312            if (removeDyingProviderLocked(app, cpr, always) || always) {
13313                // We left the provider in the launching list, need to
13314                // restart it.
13315                restart = true;
13316            }
13317
13318            cpr.provider = null;
13319            cpr.proc = null;
13320        }
13321        app.pubProviders.clear();
13322
13323        // Take care of any launching providers waiting for this process.
13324        if (checkAppInLaunchingProvidersLocked(app, false)) {
13325            restart = true;
13326        }
13327
13328        // Unregister from connected content providers.
13329        if (!app.conProviders.isEmpty()) {
13330            for (int i=0; i<app.conProviders.size(); i++) {
13331                ContentProviderConnection conn = app.conProviders.get(i);
13332                conn.provider.connections.remove(conn);
13333            }
13334            app.conProviders.clear();
13335        }
13336
13337        // At this point there may be remaining entries in mLaunchingProviders
13338        // where we were the only one waiting, so they are no longer of use.
13339        // Look for these and clean up if found.
13340        // XXX Commented out for now.  Trying to figure out a way to reproduce
13341        // the actual situation to identify what is actually going on.
13342        if (false) {
13343            for (int i=0; i<mLaunchingProviders.size(); i++) {
13344                ContentProviderRecord cpr = (ContentProviderRecord)
13345                        mLaunchingProviders.get(i);
13346                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13347                    synchronized (cpr) {
13348                        cpr.launchingApp = null;
13349                        cpr.notifyAll();
13350                    }
13351                }
13352            }
13353        }
13354
13355        skipCurrentReceiverLocked(app);
13356
13357        // Unregister any receivers.
13358        for (int i=app.receivers.size()-1; i>=0; i--) {
13359            removeReceiverLocked(app.receivers.valueAt(i));
13360        }
13361        app.receivers.clear();
13362
13363        // If the app is undergoing backup, tell the backup manager about it
13364        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13365            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13366                    + mBackupTarget.appInfo + " died during backup");
13367            try {
13368                IBackupManager bm = IBackupManager.Stub.asInterface(
13369                        ServiceManager.getService(Context.BACKUP_SERVICE));
13370                bm.agentDisconnected(app.info.packageName);
13371            } catch (RemoteException e) {
13372                // can't happen; backup manager is local
13373            }
13374        }
13375
13376        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13377            ProcessChangeItem item = mPendingProcessChanges.get(i);
13378            if (item.pid == app.pid) {
13379                mPendingProcessChanges.remove(i);
13380                mAvailProcessChanges.add(item);
13381            }
13382        }
13383        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13384
13385        // If the caller is restarting this app, then leave it in its
13386        // current lists and let the caller take care of it.
13387        if (restarting) {
13388            return;
13389        }
13390
13391        if (!app.persistent || app.isolated) {
13392            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13393                    "Removing non-persistent process during cleanup: " + app);
13394            mProcessNames.remove(app.processName, app.uid);
13395            mIsolatedProcesses.remove(app.uid);
13396            if (mHeavyWeightProcess == app) {
13397                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13398                        mHeavyWeightProcess.userId, 0));
13399                mHeavyWeightProcess = null;
13400            }
13401        } else if (!app.removed) {
13402            // This app is persistent, so we need to keep its record around.
13403            // If it is not already on the pending app list, add it there
13404            // and start a new process for it.
13405            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13406                mPersistentStartingProcesses.add(app);
13407                restart = true;
13408            }
13409        }
13410        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13411                "Clean-up removing on hold: " + app);
13412        mProcessesOnHold.remove(app);
13413
13414        if (app == mHomeProcess) {
13415            mHomeProcess = null;
13416        }
13417        if (app == mPreviousProcess) {
13418            mPreviousProcess = null;
13419        }
13420
13421        if (restart && !app.isolated) {
13422            // We have components that still need to be running in the
13423            // process, so re-launch it.
13424            mProcessNames.put(app.processName, app.uid, app);
13425            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13426        } else if (app.pid > 0 && app.pid != MY_PID) {
13427            // Goodbye!
13428            boolean removed;
13429            synchronized (mPidsSelfLocked) {
13430                mPidsSelfLocked.remove(app.pid);
13431                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13432            }
13433            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13434            if (app.isolated) {
13435                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13436            }
13437            app.setPid(0);
13438        }
13439    }
13440
13441    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13442        // Look through the content providers we are waiting to have launched,
13443        // and if any run in this process then either schedule a restart of
13444        // the process or kill the client waiting for it if this process has
13445        // gone bad.
13446        int NL = mLaunchingProviders.size();
13447        boolean restart = false;
13448        for (int i=0; i<NL; i++) {
13449            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13450            if (cpr.launchingApp == app) {
13451                if (!alwaysBad && !app.bad) {
13452                    restart = true;
13453                } else {
13454                    removeDyingProviderLocked(app, cpr, true);
13455                    // cpr should have been removed from mLaunchingProviders
13456                    NL = mLaunchingProviders.size();
13457                    i--;
13458                }
13459            }
13460        }
13461        return restart;
13462    }
13463
13464    // =========================================================
13465    // SERVICES
13466    // =========================================================
13467
13468    @Override
13469    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13470            int flags) {
13471        enforceNotIsolatedCaller("getServices");
13472        synchronized (this) {
13473            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13474        }
13475    }
13476
13477    @Override
13478    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13479        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13480        synchronized (this) {
13481            return mServices.getRunningServiceControlPanelLocked(name);
13482        }
13483    }
13484
13485    @Override
13486    public ComponentName startService(IApplicationThread caller, Intent service,
13487            String resolvedType, int userId) {
13488        enforceNotIsolatedCaller("startService");
13489        // Refuse possible leaked file descriptors
13490        if (service != null && service.hasFileDescriptors() == true) {
13491            throw new IllegalArgumentException("File descriptors passed in Intent");
13492        }
13493
13494        if (DEBUG_SERVICE)
13495            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13496        synchronized(this) {
13497            final int callingPid = Binder.getCallingPid();
13498            final int callingUid = Binder.getCallingUid();
13499            final long origId = Binder.clearCallingIdentity();
13500            ComponentName res = mServices.startServiceLocked(caller, service,
13501                    resolvedType, callingPid, callingUid, userId);
13502            Binder.restoreCallingIdentity(origId);
13503            return res;
13504        }
13505    }
13506
13507    ComponentName startServiceInPackage(int uid,
13508            Intent service, String resolvedType, int userId) {
13509        synchronized(this) {
13510            if (DEBUG_SERVICE)
13511                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13512            final long origId = Binder.clearCallingIdentity();
13513            ComponentName res = mServices.startServiceLocked(null, service,
13514                    resolvedType, -1, uid, userId);
13515            Binder.restoreCallingIdentity(origId);
13516            return res;
13517        }
13518    }
13519
13520    @Override
13521    public int stopService(IApplicationThread caller, Intent service,
13522            String resolvedType, int userId) {
13523        enforceNotIsolatedCaller("stopService");
13524        // Refuse possible leaked file descriptors
13525        if (service != null && service.hasFileDescriptors() == true) {
13526            throw new IllegalArgumentException("File descriptors passed in Intent");
13527        }
13528
13529        synchronized(this) {
13530            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13531        }
13532    }
13533
13534    @Override
13535    public IBinder peekService(Intent service, String resolvedType) {
13536        enforceNotIsolatedCaller("peekService");
13537        // Refuse possible leaked file descriptors
13538        if (service != null && service.hasFileDescriptors() == true) {
13539            throw new IllegalArgumentException("File descriptors passed in Intent");
13540        }
13541        synchronized(this) {
13542            return mServices.peekServiceLocked(service, resolvedType);
13543        }
13544    }
13545
13546    @Override
13547    public boolean stopServiceToken(ComponentName className, IBinder token,
13548            int startId) {
13549        synchronized(this) {
13550            return mServices.stopServiceTokenLocked(className, token, startId);
13551        }
13552    }
13553
13554    @Override
13555    public void setServiceForeground(ComponentName className, IBinder token,
13556            int id, Notification notification, boolean removeNotification) {
13557        synchronized(this) {
13558            mServices.setServiceForegroundLocked(className, token, id, notification,
13559                    removeNotification);
13560        }
13561    }
13562
13563    @Override
13564    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13565            boolean requireFull, String name, String callerPackage) {
13566        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13567                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13568    }
13569
13570    int unsafeConvertIncomingUser(int userId) {
13571        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13572                ? mCurrentUserId : userId;
13573    }
13574
13575    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13576            int allowMode, String name, String callerPackage) {
13577        final int callingUserId = UserHandle.getUserId(callingUid);
13578        if (callingUserId == userId) {
13579            return userId;
13580        }
13581
13582        // Note that we may be accessing mCurrentUserId outside of a lock...
13583        // shouldn't be a big deal, if this is being called outside
13584        // of a locked context there is intrinsically a race with
13585        // the value the caller will receive and someone else changing it.
13586        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13587        // we will switch to the calling user if access to the current user fails.
13588        int targetUserId = unsafeConvertIncomingUser(userId);
13589
13590        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13591            final boolean allow;
13592            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13593                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13594                // If the caller has this permission, they always pass go.  And collect $200.
13595                allow = true;
13596            } else if (allowMode == ALLOW_FULL_ONLY) {
13597                // We require full access, sucks to be you.
13598                allow = false;
13599            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13600                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13601                // If the caller does not have either permission, they are always doomed.
13602                allow = false;
13603            } else if (allowMode == ALLOW_NON_FULL) {
13604                // We are blanket allowing non-full access, you lucky caller!
13605                allow = true;
13606            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13607                // We may or may not allow this depending on whether the two users are
13608                // in the same profile.
13609                synchronized (mUserProfileGroupIdsSelfLocked) {
13610                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13611                            UserInfo.NO_PROFILE_GROUP_ID);
13612                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13613                            UserInfo.NO_PROFILE_GROUP_ID);
13614                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13615                            && callingProfile == targetProfile;
13616                }
13617            } else {
13618                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13619            }
13620            if (!allow) {
13621                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13622                    // In this case, they would like to just execute as their
13623                    // owner user instead of failing.
13624                    targetUserId = callingUserId;
13625                } else {
13626                    StringBuilder builder = new StringBuilder(128);
13627                    builder.append("Permission Denial: ");
13628                    builder.append(name);
13629                    if (callerPackage != null) {
13630                        builder.append(" from ");
13631                        builder.append(callerPackage);
13632                    }
13633                    builder.append(" asks to run as user ");
13634                    builder.append(userId);
13635                    builder.append(" but is calling from user ");
13636                    builder.append(UserHandle.getUserId(callingUid));
13637                    builder.append("; this requires ");
13638                    builder.append(INTERACT_ACROSS_USERS_FULL);
13639                    if (allowMode != ALLOW_FULL_ONLY) {
13640                        builder.append(" or ");
13641                        builder.append(INTERACT_ACROSS_USERS);
13642                    }
13643                    String msg = builder.toString();
13644                    Slog.w(TAG, msg);
13645                    throw new SecurityException(msg);
13646                }
13647            }
13648        }
13649        if (!allowAll && targetUserId < 0) {
13650            throw new IllegalArgumentException(
13651                    "Call does not support special user #" + targetUserId);
13652        }
13653        return targetUserId;
13654    }
13655
13656    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13657            String className, int flags) {
13658        boolean result = false;
13659        // For apps that don't have pre-defined UIDs, check for permission
13660        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13661            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13662                if (ActivityManager.checkUidPermission(
13663                        INTERACT_ACROSS_USERS,
13664                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13665                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13666                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13667                            + " requests FLAG_SINGLE_USER, but app does not hold "
13668                            + INTERACT_ACROSS_USERS;
13669                    Slog.w(TAG, msg);
13670                    throw new SecurityException(msg);
13671                }
13672                // Permission passed
13673                result = true;
13674            }
13675        } else if ("system".equals(componentProcessName)) {
13676            result = true;
13677        } else {
13678            // App with pre-defined UID, check if it's a persistent app
13679            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13680        }
13681        if (DEBUG_MU) {
13682            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13683                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13684        }
13685        return result;
13686    }
13687
13688    /**
13689     * Checks to see if the caller is in the same app as the singleton
13690     * component, or the component is in a special app. It allows special apps
13691     * to export singleton components but prevents exporting singleton
13692     * components for regular apps.
13693     */
13694    boolean isValidSingletonCall(int callingUid, int componentUid) {
13695        int componentAppId = UserHandle.getAppId(componentUid);
13696        return UserHandle.isSameApp(callingUid, componentUid)
13697                || componentAppId == Process.SYSTEM_UID
13698                || componentAppId == Process.PHONE_UID
13699                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13700                        == PackageManager.PERMISSION_GRANTED;
13701    }
13702
13703    public int bindService(IApplicationThread caller, IBinder token,
13704            Intent service, String resolvedType,
13705            IServiceConnection connection, int flags, int userId) {
13706        enforceNotIsolatedCaller("bindService");
13707        // Refuse possible leaked file descriptors
13708        if (service != null && service.hasFileDescriptors() == true) {
13709            throw new IllegalArgumentException("File descriptors passed in Intent");
13710        }
13711
13712        synchronized(this) {
13713            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13714                    connection, flags, userId);
13715        }
13716    }
13717
13718    public boolean unbindService(IServiceConnection connection) {
13719        synchronized (this) {
13720            return mServices.unbindServiceLocked(connection);
13721        }
13722    }
13723
13724    public void publishService(IBinder token, Intent intent, IBinder service) {
13725        // Refuse possible leaked file descriptors
13726        if (intent != null && intent.hasFileDescriptors() == true) {
13727            throw new IllegalArgumentException("File descriptors passed in Intent");
13728        }
13729
13730        synchronized(this) {
13731            if (!(token instanceof ServiceRecord)) {
13732                throw new IllegalArgumentException("Invalid service token");
13733            }
13734            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13735        }
13736    }
13737
13738    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13739        // Refuse possible leaked file descriptors
13740        if (intent != null && intent.hasFileDescriptors() == true) {
13741            throw new IllegalArgumentException("File descriptors passed in Intent");
13742        }
13743
13744        synchronized(this) {
13745            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13746        }
13747    }
13748
13749    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13750        synchronized(this) {
13751            if (!(token instanceof ServiceRecord)) {
13752                throw new IllegalArgumentException("Invalid service token");
13753            }
13754            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13755        }
13756    }
13757
13758    // =========================================================
13759    // BACKUP AND RESTORE
13760    // =========================================================
13761
13762    // Cause the target app to be launched if necessary and its backup agent
13763    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13764    // activity manager to announce its creation.
13765    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13766        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13767        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13768
13769        synchronized(this) {
13770            // !!! TODO: currently no check here that we're already bound
13771            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13772            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13773            synchronized (stats) {
13774                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13775            }
13776
13777            // Backup agent is now in use, its package can't be stopped.
13778            try {
13779                AppGlobals.getPackageManager().setPackageStoppedState(
13780                        app.packageName, false, UserHandle.getUserId(app.uid));
13781            } catch (RemoteException e) {
13782            } catch (IllegalArgumentException e) {
13783                Slog.w(TAG, "Failed trying to unstop package "
13784                        + app.packageName + ": " + e);
13785            }
13786
13787            BackupRecord r = new BackupRecord(ss, app, backupMode);
13788            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13789                    ? new ComponentName(app.packageName, app.backupAgentName)
13790                    : new ComponentName("android", "FullBackupAgent");
13791            // startProcessLocked() returns existing proc's record if it's already running
13792            ProcessRecord proc = startProcessLocked(app.processName, app,
13793                    false, 0, "backup", hostingName, false, false, false);
13794            if (proc == null) {
13795                Slog.e(TAG, "Unable to start backup agent process " + r);
13796                return false;
13797            }
13798
13799            r.app = proc;
13800            mBackupTarget = r;
13801            mBackupAppName = app.packageName;
13802
13803            // Try not to kill the process during backup
13804            updateOomAdjLocked(proc);
13805
13806            // If the process is already attached, schedule the creation of the backup agent now.
13807            // If it is not yet live, this will be done when it attaches to the framework.
13808            if (proc.thread != null) {
13809                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13810                try {
13811                    proc.thread.scheduleCreateBackupAgent(app,
13812                            compatibilityInfoForPackageLocked(app), backupMode);
13813                } catch (RemoteException e) {
13814                    // Will time out on the backup manager side
13815                }
13816            } else {
13817                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13818            }
13819            // Invariants: at this point, the target app process exists and the application
13820            // is either already running or in the process of coming up.  mBackupTarget and
13821            // mBackupAppName describe the app, so that when it binds back to the AM we
13822            // know that it's scheduled for a backup-agent operation.
13823        }
13824
13825        return true;
13826    }
13827
13828    @Override
13829    public void clearPendingBackup() {
13830        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13831        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13832
13833        synchronized (this) {
13834            mBackupTarget = null;
13835            mBackupAppName = null;
13836        }
13837    }
13838
13839    // A backup agent has just come up
13840    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13841        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13842                + " = " + agent);
13843
13844        synchronized(this) {
13845            if (!agentPackageName.equals(mBackupAppName)) {
13846                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13847                return;
13848            }
13849        }
13850
13851        long oldIdent = Binder.clearCallingIdentity();
13852        try {
13853            IBackupManager bm = IBackupManager.Stub.asInterface(
13854                    ServiceManager.getService(Context.BACKUP_SERVICE));
13855            bm.agentConnected(agentPackageName, agent);
13856        } catch (RemoteException e) {
13857            // can't happen; the backup manager service is local
13858        } catch (Exception e) {
13859            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13860            e.printStackTrace();
13861        } finally {
13862            Binder.restoreCallingIdentity(oldIdent);
13863        }
13864    }
13865
13866    // done with this agent
13867    public void unbindBackupAgent(ApplicationInfo appInfo) {
13868        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13869        if (appInfo == null) {
13870            Slog.w(TAG, "unbind backup agent for null app");
13871            return;
13872        }
13873
13874        synchronized(this) {
13875            try {
13876                if (mBackupAppName == null) {
13877                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13878                    return;
13879                }
13880
13881                if (!mBackupAppName.equals(appInfo.packageName)) {
13882                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13883                    return;
13884                }
13885
13886                // Not backing this app up any more; reset its OOM adjustment
13887                final ProcessRecord proc = mBackupTarget.app;
13888                updateOomAdjLocked(proc);
13889
13890                // If the app crashed during backup, 'thread' will be null here
13891                if (proc.thread != null) {
13892                    try {
13893                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13894                                compatibilityInfoForPackageLocked(appInfo));
13895                    } catch (Exception e) {
13896                        Slog.e(TAG, "Exception when unbinding backup agent:");
13897                        e.printStackTrace();
13898                    }
13899                }
13900            } finally {
13901                mBackupTarget = null;
13902                mBackupAppName = null;
13903            }
13904        }
13905    }
13906    // =========================================================
13907    // BROADCASTS
13908    // =========================================================
13909
13910    private final List getStickiesLocked(String action, IntentFilter filter,
13911            List cur, int userId) {
13912        final ContentResolver resolver = mContext.getContentResolver();
13913        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13914        if (stickies == null) {
13915            return cur;
13916        }
13917        final ArrayList<Intent> list = stickies.get(action);
13918        if (list == null) {
13919            return cur;
13920        }
13921        int N = list.size();
13922        for (int i=0; i<N; i++) {
13923            Intent intent = list.get(i);
13924            if (filter.match(resolver, intent, true, TAG) >= 0) {
13925                if (cur == null) {
13926                    cur = new ArrayList<Intent>();
13927                }
13928                cur.add(intent);
13929            }
13930        }
13931        return cur;
13932    }
13933
13934    boolean isPendingBroadcastProcessLocked(int pid) {
13935        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13936                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13937    }
13938
13939    void skipPendingBroadcastLocked(int pid) {
13940            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13941            for (BroadcastQueue queue : mBroadcastQueues) {
13942                queue.skipPendingBroadcastLocked(pid);
13943            }
13944    }
13945
13946    // The app just attached; send any pending broadcasts that it should receive
13947    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13948        boolean didSomething = false;
13949        for (BroadcastQueue queue : mBroadcastQueues) {
13950            didSomething |= queue.sendPendingBroadcastsLocked(app);
13951        }
13952        return didSomething;
13953    }
13954
13955    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13956            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13957        enforceNotIsolatedCaller("registerReceiver");
13958        int callingUid;
13959        int callingPid;
13960        synchronized(this) {
13961            ProcessRecord callerApp = null;
13962            if (caller != null) {
13963                callerApp = getRecordForAppLocked(caller);
13964                if (callerApp == null) {
13965                    throw new SecurityException(
13966                            "Unable to find app for caller " + caller
13967                            + " (pid=" + Binder.getCallingPid()
13968                            + ") when registering receiver " + receiver);
13969                }
13970                if (callerApp.info.uid != Process.SYSTEM_UID &&
13971                        !callerApp.pkgList.containsKey(callerPackage) &&
13972                        !"android".equals(callerPackage)) {
13973                    throw new SecurityException("Given caller package " + callerPackage
13974                            + " is not running in process " + callerApp);
13975                }
13976                callingUid = callerApp.info.uid;
13977                callingPid = callerApp.pid;
13978            } else {
13979                callerPackage = null;
13980                callingUid = Binder.getCallingUid();
13981                callingPid = Binder.getCallingPid();
13982            }
13983
13984            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13985                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
13986
13987            List allSticky = null;
13988
13989            // Look for any matching sticky broadcasts...
13990            Iterator actions = filter.actionsIterator();
13991            if (actions != null) {
13992                while (actions.hasNext()) {
13993                    String action = (String)actions.next();
13994                    allSticky = getStickiesLocked(action, filter, allSticky,
13995                            UserHandle.USER_ALL);
13996                    allSticky = getStickiesLocked(action, filter, allSticky,
13997                            UserHandle.getUserId(callingUid));
13998                }
13999            } else {
14000                allSticky = getStickiesLocked(null, filter, allSticky,
14001                        UserHandle.USER_ALL);
14002                allSticky = getStickiesLocked(null, filter, allSticky,
14003                        UserHandle.getUserId(callingUid));
14004            }
14005
14006            // The first sticky in the list is returned directly back to
14007            // the client.
14008            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14009
14010            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14011                    + ": " + sticky);
14012
14013            if (receiver == null) {
14014                return sticky;
14015            }
14016
14017            ReceiverList rl
14018                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14019            if (rl == null) {
14020                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14021                        userId, receiver);
14022                if (rl.app != null) {
14023                    rl.app.receivers.add(rl);
14024                } else {
14025                    try {
14026                        receiver.asBinder().linkToDeath(rl, 0);
14027                    } catch (RemoteException e) {
14028                        return sticky;
14029                    }
14030                    rl.linkedToDeath = true;
14031                }
14032                mRegisteredReceivers.put(receiver.asBinder(), rl);
14033            } else if (rl.uid != callingUid) {
14034                throw new IllegalArgumentException(
14035                        "Receiver requested to register for uid " + callingUid
14036                        + " was previously registered for uid " + rl.uid);
14037            } else if (rl.pid != callingPid) {
14038                throw new IllegalArgumentException(
14039                        "Receiver requested to register for pid " + callingPid
14040                        + " was previously registered for pid " + rl.pid);
14041            } else if (rl.userId != userId) {
14042                throw new IllegalArgumentException(
14043                        "Receiver requested to register for user " + userId
14044                        + " was previously registered for user " + rl.userId);
14045            }
14046            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14047                    permission, callingUid, userId);
14048            rl.add(bf);
14049            if (!bf.debugCheck()) {
14050                Slog.w(TAG, "==> For Dynamic broadast");
14051            }
14052            mReceiverResolver.addFilter(bf);
14053
14054            // Enqueue broadcasts for all existing stickies that match
14055            // this filter.
14056            if (allSticky != null) {
14057                ArrayList receivers = new ArrayList();
14058                receivers.add(bf);
14059
14060                int N = allSticky.size();
14061                for (int i=0; i<N; i++) {
14062                    Intent intent = (Intent)allSticky.get(i);
14063                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14064                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14065                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14066                            null, null, false, true, true, -1);
14067                    queue.enqueueParallelBroadcastLocked(r);
14068                    queue.scheduleBroadcastsLocked();
14069                }
14070            }
14071
14072            return sticky;
14073        }
14074    }
14075
14076    public void unregisterReceiver(IIntentReceiver receiver) {
14077        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14078
14079        final long origId = Binder.clearCallingIdentity();
14080        try {
14081            boolean doTrim = false;
14082
14083            synchronized(this) {
14084                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14085                if (rl != null) {
14086                    if (rl.curBroadcast != null) {
14087                        BroadcastRecord r = rl.curBroadcast;
14088                        final boolean doNext = finishReceiverLocked(
14089                                receiver.asBinder(), r.resultCode, r.resultData,
14090                                r.resultExtras, r.resultAbort);
14091                        if (doNext) {
14092                            doTrim = true;
14093                            r.queue.processNextBroadcast(false);
14094                        }
14095                    }
14096
14097                    if (rl.app != null) {
14098                        rl.app.receivers.remove(rl);
14099                    }
14100                    removeReceiverLocked(rl);
14101                    if (rl.linkedToDeath) {
14102                        rl.linkedToDeath = false;
14103                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14104                    }
14105                }
14106            }
14107
14108            // If we actually concluded any broadcasts, we might now be able
14109            // to trim the recipients' apps from our working set
14110            if (doTrim) {
14111                trimApplications();
14112                return;
14113            }
14114
14115        } finally {
14116            Binder.restoreCallingIdentity(origId);
14117        }
14118    }
14119
14120    void removeReceiverLocked(ReceiverList rl) {
14121        mRegisteredReceivers.remove(rl.receiver.asBinder());
14122        int N = rl.size();
14123        for (int i=0; i<N; i++) {
14124            mReceiverResolver.removeFilter(rl.get(i));
14125        }
14126    }
14127
14128    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14129        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14130            ProcessRecord r = mLruProcesses.get(i);
14131            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14132                try {
14133                    r.thread.dispatchPackageBroadcast(cmd, packages);
14134                } catch (RemoteException ex) {
14135                }
14136            }
14137        }
14138    }
14139
14140    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14141            int[] users) {
14142        List<ResolveInfo> receivers = null;
14143        try {
14144            HashSet<ComponentName> singleUserReceivers = null;
14145            boolean scannedFirstReceivers = false;
14146            for (int user : users) {
14147                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14148                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14149                if (user != 0 && newReceivers != null) {
14150                    // If this is not the primary user, we need to check for
14151                    // any receivers that should be filtered out.
14152                    for (int i=0; i<newReceivers.size(); i++) {
14153                        ResolveInfo ri = newReceivers.get(i);
14154                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14155                            newReceivers.remove(i);
14156                            i--;
14157                        }
14158                    }
14159                }
14160                if (newReceivers != null && newReceivers.size() == 0) {
14161                    newReceivers = null;
14162                }
14163                if (receivers == null) {
14164                    receivers = newReceivers;
14165                } else if (newReceivers != null) {
14166                    // We need to concatenate the additional receivers
14167                    // found with what we have do far.  This would be easy,
14168                    // but we also need to de-dup any receivers that are
14169                    // singleUser.
14170                    if (!scannedFirstReceivers) {
14171                        // Collect any single user receivers we had already retrieved.
14172                        scannedFirstReceivers = true;
14173                        for (int i=0; i<receivers.size(); i++) {
14174                            ResolveInfo ri = receivers.get(i);
14175                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14176                                ComponentName cn = new ComponentName(
14177                                        ri.activityInfo.packageName, ri.activityInfo.name);
14178                                if (singleUserReceivers == null) {
14179                                    singleUserReceivers = new HashSet<ComponentName>();
14180                                }
14181                                singleUserReceivers.add(cn);
14182                            }
14183                        }
14184                    }
14185                    // Add the new results to the existing results, tracking
14186                    // and de-dupping single user receivers.
14187                    for (int i=0; i<newReceivers.size(); i++) {
14188                        ResolveInfo ri = newReceivers.get(i);
14189                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14190                            ComponentName cn = new ComponentName(
14191                                    ri.activityInfo.packageName, ri.activityInfo.name);
14192                            if (singleUserReceivers == null) {
14193                                singleUserReceivers = new HashSet<ComponentName>();
14194                            }
14195                            if (!singleUserReceivers.contains(cn)) {
14196                                singleUserReceivers.add(cn);
14197                                receivers.add(ri);
14198                            }
14199                        } else {
14200                            receivers.add(ri);
14201                        }
14202                    }
14203                }
14204            }
14205        } catch (RemoteException ex) {
14206            // pm is in same process, this will never happen.
14207        }
14208        return receivers;
14209    }
14210
14211    private final int broadcastIntentLocked(ProcessRecord callerApp,
14212            String callerPackage, Intent intent, String resolvedType,
14213            IIntentReceiver resultTo, int resultCode, String resultData,
14214            Bundle map, String requiredPermission, int appOp,
14215            boolean ordered, boolean sticky, int callingPid, int callingUid,
14216            int userId) {
14217        intent = new Intent(intent);
14218
14219        // By default broadcasts do not go to stopped apps.
14220        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14221
14222        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14223            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14224            + " ordered=" + ordered + " userid=" + userId);
14225        if ((resultTo != null) && !ordered) {
14226            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14227        }
14228
14229        userId = handleIncomingUser(callingPid, callingUid, userId,
14230                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14231
14232        // Make sure that the user who is receiving this broadcast is started.
14233        // If not, we will just skip it.
14234
14235
14236        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14237            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14238                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14239                Slog.w(TAG, "Skipping broadcast of " + intent
14240                        + ": user " + userId + " is stopped");
14241                return ActivityManager.BROADCAST_SUCCESS;
14242            }
14243        }
14244
14245        /*
14246         * Prevent non-system code (defined here to be non-persistent
14247         * processes) from sending protected broadcasts.
14248         */
14249        int callingAppId = UserHandle.getAppId(callingUid);
14250        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14251            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14252            || callingAppId == Process.NFC_UID || callingUid == 0) {
14253            // Always okay.
14254        } else if (callerApp == null || !callerApp.persistent) {
14255            try {
14256                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14257                        intent.getAction())) {
14258                    String msg = "Permission Denial: not allowed to send broadcast "
14259                            + intent.getAction() + " from pid="
14260                            + callingPid + ", uid=" + callingUid;
14261                    Slog.w(TAG, msg);
14262                    throw new SecurityException(msg);
14263                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14264                    // Special case for compatibility: we don't want apps to send this,
14265                    // but historically it has not been protected and apps may be using it
14266                    // to poke their own app widget.  So, instead of making it protected,
14267                    // just limit it to the caller.
14268                    if (callerApp == null) {
14269                        String msg = "Permission Denial: not allowed to send broadcast "
14270                                + intent.getAction() + " from unknown caller.";
14271                        Slog.w(TAG, msg);
14272                        throw new SecurityException(msg);
14273                    } else if (intent.getComponent() != null) {
14274                        // They are good enough to send to an explicit component...  verify
14275                        // it is being sent to the calling app.
14276                        if (!intent.getComponent().getPackageName().equals(
14277                                callerApp.info.packageName)) {
14278                            String msg = "Permission Denial: not allowed to send broadcast "
14279                                    + intent.getAction() + " to "
14280                                    + intent.getComponent().getPackageName() + " from "
14281                                    + callerApp.info.packageName;
14282                            Slog.w(TAG, msg);
14283                            throw new SecurityException(msg);
14284                        }
14285                    } else {
14286                        // Limit broadcast to their own package.
14287                        intent.setPackage(callerApp.info.packageName);
14288                    }
14289                }
14290            } catch (RemoteException e) {
14291                Slog.w(TAG, "Remote exception", e);
14292                return ActivityManager.BROADCAST_SUCCESS;
14293            }
14294        }
14295
14296        // Handle special intents: if this broadcast is from the package
14297        // manager about a package being removed, we need to remove all of
14298        // its activities from the history stack.
14299        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14300                intent.getAction());
14301        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14302                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14303                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14304                || uidRemoved) {
14305            if (checkComponentPermission(
14306                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14307                    callingPid, callingUid, -1, true)
14308                    == PackageManager.PERMISSION_GRANTED) {
14309                if (uidRemoved) {
14310                    final Bundle intentExtras = intent.getExtras();
14311                    final int uid = intentExtras != null
14312                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14313                    if (uid >= 0) {
14314                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14315                        synchronized (bs) {
14316                            bs.removeUidStatsLocked(uid);
14317                        }
14318                        mAppOpsService.uidRemoved(uid);
14319                    }
14320                } else {
14321                    // If resources are unavailable just force stop all
14322                    // those packages and flush the attribute cache as well.
14323                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14324                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14325                        if (list != null && (list.length > 0)) {
14326                            for (String pkg : list) {
14327                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14328                                        "storage unmount");
14329                            }
14330                            sendPackageBroadcastLocked(
14331                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14332                        }
14333                    } else {
14334                        Uri data = intent.getData();
14335                        String ssp;
14336                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14337                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14338                                    intent.getAction());
14339                            boolean fullUninstall = removed &&
14340                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14341                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14342                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14343                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14344                                        false, fullUninstall, userId,
14345                                        removed ? "pkg removed" : "pkg changed");
14346                            }
14347                            if (removed) {
14348                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14349                                        new String[] {ssp}, userId);
14350                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14351                                    mAppOpsService.packageRemoved(
14352                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14353
14354                                    // Remove all permissions granted from/to this package
14355                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14356                                }
14357                            }
14358                        }
14359                    }
14360                }
14361            } else {
14362                String msg = "Permission Denial: " + intent.getAction()
14363                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14364                        + ", uid=" + callingUid + ")"
14365                        + " requires "
14366                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14367                Slog.w(TAG, msg);
14368                throw new SecurityException(msg);
14369            }
14370
14371        // Special case for adding a package: by default turn on compatibility
14372        // mode.
14373        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14374            Uri data = intent.getData();
14375            String ssp;
14376            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14377                mCompatModePackages.handlePackageAddedLocked(ssp,
14378                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14379            }
14380        }
14381
14382        /*
14383         * If this is the time zone changed action, queue up a message that will reset the timezone
14384         * of all currently running processes. This message will get queued up before the broadcast
14385         * happens.
14386         */
14387        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14388            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14389        }
14390
14391        /*
14392         * If the user set the time, let all running processes know.
14393         */
14394        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14395            final int is24Hour = intent.getBooleanExtra(
14396                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14397            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14398        }
14399
14400        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14401            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14402        }
14403
14404        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14405            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14406            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14407        }
14408
14409        // Add to the sticky list if requested.
14410        if (sticky) {
14411            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14412                    callingPid, callingUid)
14413                    != PackageManager.PERMISSION_GRANTED) {
14414                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14415                        + callingPid + ", uid=" + callingUid
14416                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14417                Slog.w(TAG, msg);
14418                throw new SecurityException(msg);
14419            }
14420            if (requiredPermission != null) {
14421                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14422                        + " and enforce permission " + requiredPermission);
14423                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14424            }
14425            if (intent.getComponent() != null) {
14426                throw new SecurityException(
14427                        "Sticky broadcasts can't target a specific component");
14428            }
14429            // We use userId directly here, since the "all" target is maintained
14430            // as a separate set of sticky broadcasts.
14431            if (userId != UserHandle.USER_ALL) {
14432                // But first, if this is not a broadcast to all users, then
14433                // make sure it doesn't conflict with an existing broadcast to
14434                // all users.
14435                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14436                        UserHandle.USER_ALL);
14437                if (stickies != null) {
14438                    ArrayList<Intent> list = stickies.get(intent.getAction());
14439                    if (list != null) {
14440                        int N = list.size();
14441                        int i;
14442                        for (i=0; i<N; i++) {
14443                            if (intent.filterEquals(list.get(i))) {
14444                                throw new IllegalArgumentException(
14445                                        "Sticky broadcast " + intent + " for user "
14446                                        + userId + " conflicts with existing global broadcast");
14447                            }
14448                        }
14449                    }
14450                }
14451            }
14452            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14453            if (stickies == null) {
14454                stickies = new ArrayMap<String, ArrayList<Intent>>();
14455                mStickyBroadcasts.put(userId, stickies);
14456            }
14457            ArrayList<Intent> list = stickies.get(intent.getAction());
14458            if (list == null) {
14459                list = new ArrayList<Intent>();
14460                stickies.put(intent.getAction(), list);
14461            }
14462            int N = list.size();
14463            int i;
14464            for (i=0; i<N; i++) {
14465                if (intent.filterEquals(list.get(i))) {
14466                    // This sticky already exists, replace it.
14467                    list.set(i, new Intent(intent));
14468                    break;
14469                }
14470            }
14471            if (i >= N) {
14472                list.add(new Intent(intent));
14473            }
14474        }
14475
14476        int[] users;
14477        if (userId == UserHandle.USER_ALL) {
14478            // Caller wants broadcast to go to all started users.
14479            users = mStartedUserArray;
14480        } else {
14481            // Caller wants broadcast to go to one specific user.
14482            users = new int[] {userId};
14483        }
14484
14485        // Figure out who all will receive this broadcast.
14486        List receivers = null;
14487        List<BroadcastFilter> registeredReceivers = null;
14488        // Need to resolve the intent to interested receivers...
14489        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14490                 == 0) {
14491            receivers = collectReceiverComponents(intent, resolvedType, users);
14492        }
14493        if (intent.getComponent() == null) {
14494            registeredReceivers = mReceiverResolver.queryIntent(intent,
14495                    resolvedType, false, userId);
14496        }
14497
14498        final boolean replacePending =
14499                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14500
14501        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14502                + " replacePending=" + replacePending);
14503
14504        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14505        if (!ordered && NR > 0) {
14506            // If we are not serializing this broadcast, then send the
14507            // registered receivers separately so they don't wait for the
14508            // components to be launched.
14509            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14510            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14511                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14512                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14513                    ordered, sticky, false, userId);
14514            if (DEBUG_BROADCAST) Slog.v(
14515                    TAG, "Enqueueing parallel broadcast " + r);
14516            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14517            if (!replaced) {
14518                queue.enqueueParallelBroadcastLocked(r);
14519                queue.scheduleBroadcastsLocked();
14520            }
14521            registeredReceivers = null;
14522            NR = 0;
14523        }
14524
14525        // Merge into one list.
14526        int ir = 0;
14527        if (receivers != null) {
14528            // A special case for PACKAGE_ADDED: do not allow the package
14529            // being added to see this broadcast.  This prevents them from
14530            // using this as a back door to get run as soon as they are
14531            // installed.  Maybe in the future we want to have a special install
14532            // broadcast or such for apps, but we'd like to deliberately make
14533            // this decision.
14534            String skipPackages[] = null;
14535            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14536                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14537                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14538                Uri data = intent.getData();
14539                if (data != null) {
14540                    String pkgName = data.getSchemeSpecificPart();
14541                    if (pkgName != null) {
14542                        skipPackages = new String[] { pkgName };
14543                    }
14544                }
14545            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14546                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14547            }
14548            if (skipPackages != null && (skipPackages.length > 0)) {
14549                for (String skipPackage : skipPackages) {
14550                    if (skipPackage != null) {
14551                        int NT = receivers.size();
14552                        for (int it=0; it<NT; it++) {
14553                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14554                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14555                                receivers.remove(it);
14556                                it--;
14557                                NT--;
14558                            }
14559                        }
14560                    }
14561                }
14562            }
14563
14564            int NT = receivers != null ? receivers.size() : 0;
14565            int it = 0;
14566            ResolveInfo curt = null;
14567            BroadcastFilter curr = null;
14568            while (it < NT && ir < NR) {
14569                if (curt == null) {
14570                    curt = (ResolveInfo)receivers.get(it);
14571                }
14572                if (curr == null) {
14573                    curr = registeredReceivers.get(ir);
14574                }
14575                if (curr.getPriority() >= curt.priority) {
14576                    // Insert this broadcast record into the final list.
14577                    receivers.add(it, curr);
14578                    ir++;
14579                    curr = null;
14580                    it++;
14581                    NT++;
14582                } else {
14583                    // Skip to the next ResolveInfo in the final list.
14584                    it++;
14585                    curt = null;
14586                }
14587            }
14588        }
14589        while (ir < NR) {
14590            if (receivers == null) {
14591                receivers = new ArrayList();
14592            }
14593            receivers.add(registeredReceivers.get(ir));
14594            ir++;
14595        }
14596
14597        if ((receivers != null && receivers.size() > 0)
14598                || resultTo != null) {
14599            BroadcastQueue queue = broadcastQueueForIntent(intent);
14600            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14601                    callerPackage, callingPid, callingUid, resolvedType,
14602                    requiredPermission, appOp, receivers, resultTo, resultCode,
14603                    resultData, map, ordered, sticky, false, userId);
14604            if (DEBUG_BROADCAST) Slog.v(
14605                    TAG, "Enqueueing ordered broadcast " + r
14606                    + ": prev had " + queue.mOrderedBroadcasts.size());
14607            if (DEBUG_BROADCAST) {
14608                int seq = r.intent.getIntExtra("seq", -1);
14609                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14610            }
14611            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14612            if (!replaced) {
14613                queue.enqueueOrderedBroadcastLocked(r);
14614                queue.scheduleBroadcastsLocked();
14615            }
14616        }
14617
14618        return ActivityManager.BROADCAST_SUCCESS;
14619    }
14620
14621    final Intent verifyBroadcastLocked(Intent intent) {
14622        // Refuse possible leaked file descriptors
14623        if (intent != null && intent.hasFileDescriptors() == true) {
14624            throw new IllegalArgumentException("File descriptors passed in Intent");
14625        }
14626
14627        int flags = intent.getFlags();
14628
14629        if (!mProcessesReady) {
14630            // if the caller really truly claims to know what they're doing, go
14631            // ahead and allow the broadcast without launching any receivers
14632            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14633                intent = new Intent(intent);
14634                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14635            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14636                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14637                        + " before boot completion");
14638                throw new IllegalStateException("Cannot broadcast before boot completed");
14639            }
14640        }
14641
14642        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14643            throw new IllegalArgumentException(
14644                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14645        }
14646
14647        return intent;
14648    }
14649
14650    public final int broadcastIntent(IApplicationThread caller,
14651            Intent intent, String resolvedType, IIntentReceiver resultTo,
14652            int resultCode, String resultData, Bundle map,
14653            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14654        enforceNotIsolatedCaller("broadcastIntent");
14655        synchronized(this) {
14656            intent = verifyBroadcastLocked(intent);
14657
14658            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14659            final int callingPid = Binder.getCallingPid();
14660            final int callingUid = Binder.getCallingUid();
14661            final long origId = Binder.clearCallingIdentity();
14662            int res = broadcastIntentLocked(callerApp,
14663                    callerApp != null ? callerApp.info.packageName : null,
14664                    intent, resolvedType, resultTo,
14665                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14666                    callingPid, callingUid, userId);
14667            Binder.restoreCallingIdentity(origId);
14668            return res;
14669        }
14670    }
14671
14672    int broadcastIntentInPackage(String packageName, int uid,
14673            Intent intent, String resolvedType, IIntentReceiver resultTo,
14674            int resultCode, String resultData, Bundle map,
14675            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14676        synchronized(this) {
14677            intent = verifyBroadcastLocked(intent);
14678
14679            final long origId = Binder.clearCallingIdentity();
14680            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14681                    resultTo, resultCode, resultData, map, requiredPermission,
14682                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14683            Binder.restoreCallingIdentity(origId);
14684            return res;
14685        }
14686    }
14687
14688    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14689        // Refuse possible leaked file descriptors
14690        if (intent != null && intent.hasFileDescriptors() == true) {
14691            throw new IllegalArgumentException("File descriptors passed in Intent");
14692        }
14693
14694        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14695                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14696
14697        synchronized(this) {
14698            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14699                    != PackageManager.PERMISSION_GRANTED) {
14700                String msg = "Permission Denial: unbroadcastIntent() from pid="
14701                        + Binder.getCallingPid()
14702                        + ", uid=" + Binder.getCallingUid()
14703                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14704                Slog.w(TAG, msg);
14705                throw new SecurityException(msg);
14706            }
14707            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14708            if (stickies != null) {
14709                ArrayList<Intent> list = stickies.get(intent.getAction());
14710                if (list != null) {
14711                    int N = list.size();
14712                    int i;
14713                    for (i=0; i<N; i++) {
14714                        if (intent.filterEquals(list.get(i))) {
14715                            list.remove(i);
14716                            break;
14717                        }
14718                    }
14719                    if (list.size() <= 0) {
14720                        stickies.remove(intent.getAction());
14721                    }
14722                }
14723                if (stickies.size() <= 0) {
14724                    mStickyBroadcasts.remove(userId);
14725                }
14726            }
14727        }
14728    }
14729
14730    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14731            String resultData, Bundle resultExtras, boolean resultAbort) {
14732        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14733        if (r == null) {
14734            Slog.w(TAG, "finishReceiver called but not found on queue");
14735            return false;
14736        }
14737
14738        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14739    }
14740
14741    void backgroundServicesFinishedLocked(int userId) {
14742        for (BroadcastQueue queue : mBroadcastQueues) {
14743            queue.backgroundServicesFinishedLocked(userId);
14744        }
14745    }
14746
14747    public void finishReceiver(IBinder who, int resultCode, String resultData,
14748            Bundle resultExtras, boolean resultAbort) {
14749        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14750
14751        // Refuse possible leaked file descriptors
14752        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14753            throw new IllegalArgumentException("File descriptors passed in Bundle");
14754        }
14755
14756        final long origId = Binder.clearCallingIdentity();
14757        try {
14758            boolean doNext = false;
14759            BroadcastRecord r;
14760
14761            synchronized(this) {
14762                r = broadcastRecordForReceiverLocked(who);
14763                if (r != null) {
14764                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14765                        resultData, resultExtras, resultAbort, true);
14766                }
14767            }
14768
14769            if (doNext) {
14770                r.queue.processNextBroadcast(false);
14771            }
14772            trimApplications();
14773        } finally {
14774            Binder.restoreCallingIdentity(origId);
14775        }
14776    }
14777
14778    // =========================================================
14779    // INSTRUMENTATION
14780    // =========================================================
14781
14782    public boolean startInstrumentation(ComponentName className,
14783            String profileFile, int flags, Bundle arguments,
14784            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14785            int userId, String abiOverride) {
14786        enforceNotIsolatedCaller("startInstrumentation");
14787        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14788                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14789        // Refuse possible leaked file descriptors
14790        if (arguments != null && arguments.hasFileDescriptors()) {
14791            throw new IllegalArgumentException("File descriptors passed in Bundle");
14792        }
14793
14794        synchronized(this) {
14795            InstrumentationInfo ii = null;
14796            ApplicationInfo ai = null;
14797            try {
14798                ii = mContext.getPackageManager().getInstrumentationInfo(
14799                    className, STOCK_PM_FLAGS);
14800                ai = AppGlobals.getPackageManager().getApplicationInfo(
14801                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14802            } catch (PackageManager.NameNotFoundException e) {
14803            } catch (RemoteException e) {
14804            }
14805            if (ii == null) {
14806                reportStartInstrumentationFailure(watcher, className,
14807                        "Unable to find instrumentation info for: " + className);
14808                return false;
14809            }
14810            if (ai == null) {
14811                reportStartInstrumentationFailure(watcher, className,
14812                        "Unable to find instrumentation target package: " + ii.targetPackage);
14813                return false;
14814            }
14815
14816            int match = mContext.getPackageManager().checkSignatures(
14817                    ii.targetPackage, ii.packageName);
14818            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14819                String msg = "Permission Denial: starting instrumentation "
14820                        + className + " from pid="
14821                        + Binder.getCallingPid()
14822                        + ", uid=" + Binder.getCallingPid()
14823                        + " not allowed because package " + ii.packageName
14824                        + " does not have a signature matching the target "
14825                        + ii.targetPackage;
14826                reportStartInstrumentationFailure(watcher, className, msg);
14827                throw new SecurityException(msg);
14828            }
14829
14830            final long origId = Binder.clearCallingIdentity();
14831            // Instrumentation can kill and relaunch even persistent processes
14832            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14833                    "start instr");
14834            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14835            app.instrumentationClass = className;
14836            app.instrumentationInfo = ai;
14837            app.instrumentationProfileFile = profileFile;
14838            app.instrumentationArguments = arguments;
14839            app.instrumentationWatcher = watcher;
14840            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14841            app.instrumentationResultClass = className;
14842            Binder.restoreCallingIdentity(origId);
14843        }
14844
14845        return true;
14846    }
14847
14848    /**
14849     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14850     * error to the logs, but if somebody is watching, send the report there too.  This enables
14851     * the "am" command to report errors with more information.
14852     *
14853     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14854     * @param cn The component name of the instrumentation.
14855     * @param report The error report.
14856     */
14857    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14858            ComponentName cn, String report) {
14859        Slog.w(TAG, report);
14860        try {
14861            if (watcher != null) {
14862                Bundle results = new Bundle();
14863                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14864                results.putString("Error", report);
14865                watcher.instrumentationStatus(cn, -1, results);
14866            }
14867        } catch (RemoteException e) {
14868            Slog.w(TAG, e);
14869        }
14870    }
14871
14872    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14873        if (app.instrumentationWatcher != null) {
14874            try {
14875                // NOTE:  IInstrumentationWatcher *must* be oneway here
14876                app.instrumentationWatcher.instrumentationFinished(
14877                    app.instrumentationClass,
14878                    resultCode,
14879                    results);
14880            } catch (RemoteException e) {
14881            }
14882        }
14883        if (app.instrumentationUiAutomationConnection != null) {
14884            try {
14885                app.instrumentationUiAutomationConnection.shutdown();
14886            } catch (RemoteException re) {
14887                /* ignore */
14888            }
14889            // Only a UiAutomation can set this flag and now that
14890            // it is finished we make sure it is reset to its default.
14891            mUserIsMonkey = false;
14892        }
14893        app.instrumentationWatcher = null;
14894        app.instrumentationUiAutomationConnection = null;
14895        app.instrumentationClass = null;
14896        app.instrumentationInfo = null;
14897        app.instrumentationProfileFile = null;
14898        app.instrumentationArguments = null;
14899
14900        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14901                "finished inst");
14902    }
14903
14904    public void finishInstrumentation(IApplicationThread target,
14905            int resultCode, Bundle results) {
14906        int userId = UserHandle.getCallingUserId();
14907        // Refuse possible leaked file descriptors
14908        if (results != null && results.hasFileDescriptors()) {
14909            throw new IllegalArgumentException("File descriptors passed in Intent");
14910        }
14911
14912        synchronized(this) {
14913            ProcessRecord app = getRecordForAppLocked(target);
14914            if (app == null) {
14915                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14916                return;
14917            }
14918            final long origId = Binder.clearCallingIdentity();
14919            finishInstrumentationLocked(app, resultCode, results);
14920            Binder.restoreCallingIdentity(origId);
14921        }
14922    }
14923
14924    // =========================================================
14925    // CONFIGURATION
14926    // =========================================================
14927
14928    public ConfigurationInfo getDeviceConfigurationInfo() {
14929        ConfigurationInfo config = new ConfigurationInfo();
14930        synchronized (this) {
14931            config.reqTouchScreen = mConfiguration.touchscreen;
14932            config.reqKeyboardType = mConfiguration.keyboard;
14933            config.reqNavigation = mConfiguration.navigation;
14934            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14935                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14936                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14937            }
14938            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14939                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14940                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14941            }
14942            config.reqGlEsVersion = GL_ES_VERSION;
14943        }
14944        return config;
14945    }
14946
14947    ActivityStack getFocusedStack() {
14948        return mStackSupervisor.getFocusedStack();
14949    }
14950
14951    public Configuration getConfiguration() {
14952        Configuration ci;
14953        synchronized(this) {
14954            ci = new Configuration(mConfiguration);
14955        }
14956        return ci;
14957    }
14958
14959    public void updatePersistentConfiguration(Configuration values) {
14960        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14961                "updateConfiguration()");
14962        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14963                "updateConfiguration()");
14964        if (values == null) {
14965            throw new NullPointerException("Configuration must not be null");
14966        }
14967
14968        synchronized(this) {
14969            final long origId = Binder.clearCallingIdentity();
14970            updateConfigurationLocked(values, null, true, false);
14971            Binder.restoreCallingIdentity(origId);
14972        }
14973    }
14974
14975    public void updateConfiguration(Configuration values) {
14976        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14977                "updateConfiguration()");
14978
14979        synchronized(this) {
14980            if (values == null && mWindowManager != null) {
14981                // sentinel: fetch the current configuration from the window manager
14982                values = mWindowManager.computeNewConfiguration();
14983            }
14984
14985            if (mWindowManager != null) {
14986                mProcessList.applyDisplaySize(mWindowManager);
14987            }
14988
14989            final long origId = Binder.clearCallingIdentity();
14990            if (values != null) {
14991                Settings.System.clearConfiguration(values);
14992            }
14993            updateConfigurationLocked(values, null, false, false);
14994            Binder.restoreCallingIdentity(origId);
14995        }
14996    }
14997
14998    /**
14999     * Do either or both things: (1) change the current configuration, and (2)
15000     * make sure the given activity is running with the (now) current
15001     * configuration.  Returns true if the activity has been left running, or
15002     * false if <var>starting</var> is being destroyed to match the new
15003     * configuration.
15004     * @param persistent TODO
15005     */
15006    boolean updateConfigurationLocked(Configuration values,
15007            ActivityRecord starting, boolean persistent, boolean initLocale) {
15008        int changes = 0;
15009
15010        if (values != null) {
15011            Configuration newConfig = new Configuration(mConfiguration);
15012            changes = newConfig.updateFrom(values);
15013            if (changes != 0) {
15014                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15015                    Slog.i(TAG, "Updating configuration to: " + values);
15016                }
15017
15018                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15019
15020                if (values.locale != null && !initLocale) {
15021                    saveLocaleLocked(values.locale,
15022                                     !values.locale.equals(mConfiguration.locale),
15023                                     values.userSetLocale);
15024                }
15025
15026                mConfigurationSeq++;
15027                if (mConfigurationSeq <= 0) {
15028                    mConfigurationSeq = 1;
15029                }
15030                newConfig.seq = mConfigurationSeq;
15031                mConfiguration = newConfig;
15032                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15033                //mUsageStatsService.noteStartConfig(newConfig);
15034
15035                final Configuration configCopy = new Configuration(mConfiguration);
15036
15037                // TODO: If our config changes, should we auto dismiss any currently
15038                // showing dialogs?
15039                mShowDialogs = shouldShowDialogs(newConfig);
15040
15041                AttributeCache ac = AttributeCache.instance();
15042                if (ac != null) {
15043                    ac.updateConfiguration(configCopy);
15044                }
15045
15046                // Make sure all resources in our process are updated
15047                // right now, so that anyone who is going to retrieve
15048                // resource values after we return will be sure to get
15049                // the new ones.  This is especially important during
15050                // boot, where the first config change needs to guarantee
15051                // all resources have that config before following boot
15052                // code is executed.
15053                mSystemThread.applyConfigurationToResources(configCopy);
15054
15055                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15056                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15057                    msg.obj = new Configuration(configCopy);
15058                    mHandler.sendMessage(msg);
15059                }
15060
15061                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15062                    ProcessRecord app = mLruProcesses.get(i);
15063                    try {
15064                        if (app.thread != null) {
15065                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15066                                    + app.processName + " new config " + mConfiguration);
15067                            app.thread.scheduleConfigurationChanged(configCopy);
15068                        }
15069                    } catch (Exception e) {
15070                    }
15071                }
15072                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15073                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15074                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15075                        | Intent.FLAG_RECEIVER_FOREGROUND);
15076                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15077                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15078                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15079                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15080                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15081                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15082                    broadcastIntentLocked(null, null, intent,
15083                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15084                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15085                }
15086            }
15087        }
15088
15089        boolean kept = true;
15090        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15091        // mainStack is null during startup.
15092        if (mainStack != null) {
15093            if (changes != 0 && starting == null) {
15094                // If the configuration changed, and the caller is not already
15095                // in the process of starting an activity, then find the top
15096                // activity to check if its configuration needs to change.
15097                starting = mainStack.topRunningActivityLocked(null);
15098            }
15099
15100            if (starting != null) {
15101                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15102                // And we need to make sure at this point that all other activities
15103                // are made visible with the correct configuration.
15104                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15105            }
15106        }
15107
15108        if (values != null && mWindowManager != null) {
15109            mWindowManager.setNewConfiguration(mConfiguration);
15110        }
15111
15112        return kept;
15113    }
15114
15115    /**
15116     * Decide based on the configuration whether we should shouw the ANR,
15117     * crash, etc dialogs.  The idea is that if there is no affordnace to
15118     * press the on-screen buttons, we shouldn't show the dialog.
15119     *
15120     * A thought: SystemUI might also want to get told about this, the Power
15121     * dialog / global actions also might want different behaviors.
15122     */
15123    private static final boolean shouldShowDialogs(Configuration config) {
15124        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15125                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15126    }
15127
15128    /**
15129     * Save the locale.  You must be inside a synchronized (this) block.
15130     */
15131    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15132        if(isDiff) {
15133            SystemProperties.set("user.language", l.getLanguage());
15134            SystemProperties.set("user.region", l.getCountry());
15135        }
15136
15137        if(isPersist) {
15138            SystemProperties.set("persist.sys.language", l.getLanguage());
15139            SystemProperties.set("persist.sys.country", l.getCountry());
15140            SystemProperties.set("persist.sys.localevar", l.getVariant());
15141        }
15142    }
15143
15144    @Override
15145    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15146        ActivityRecord srec = ActivityRecord.forToken(token);
15147        return srec != null && srec.task.affinity != null &&
15148                srec.task.affinity.equals(destAffinity);
15149    }
15150
15151    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15152            Intent resultData) {
15153
15154        synchronized (this) {
15155            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15156            if (stack != null) {
15157                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15158            }
15159            return false;
15160        }
15161    }
15162
15163    public int getLaunchedFromUid(IBinder activityToken) {
15164        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15165        if (srec == null) {
15166            return -1;
15167        }
15168        return srec.launchedFromUid;
15169    }
15170
15171    public String getLaunchedFromPackage(IBinder activityToken) {
15172        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15173        if (srec == null) {
15174            return null;
15175        }
15176        return srec.launchedFromPackage;
15177    }
15178
15179    // =========================================================
15180    // LIFETIME MANAGEMENT
15181    // =========================================================
15182
15183    // Returns which broadcast queue the app is the current [or imminent] receiver
15184    // on, or 'null' if the app is not an active broadcast recipient.
15185    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15186        BroadcastRecord r = app.curReceiver;
15187        if (r != null) {
15188            return r.queue;
15189        }
15190
15191        // It's not the current receiver, but it might be starting up to become one
15192        synchronized (this) {
15193            for (BroadcastQueue queue : mBroadcastQueues) {
15194                r = queue.mPendingBroadcast;
15195                if (r != null && r.curApp == app) {
15196                    // found it; report which queue it's in
15197                    return queue;
15198                }
15199            }
15200        }
15201
15202        return null;
15203    }
15204
15205    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15206            boolean doingAll, long now) {
15207        if (mAdjSeq == app.adjSeq) {
15208            // This adjustment has already been computed.
15209            return app.curRawAdj;
15210        }
15211
15212        if (app.thread == null) {
15213            app.adjSeq = mAdjSeq;
15214            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15215            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15216            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15217        }
15218
15219        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15220        app.adjSource = null;
15221        app.adjTarget = null;
15222        app.empty = false;
15223        app.cached = false;
15224
15225        final int activitiesSize = app.activities.size();
15226
15227        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15228            // The max adjustment doesn't allow this app to be anything
15229            // below foreground, so it is not worth doing work for it.
15230            app.adjType = "fixed";
15231            app.adjSeq = mAdjSeq;
15232            app.curRawAdj = app.maxAdj;
15233            app.foregroundActivities = false;
15234            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15235            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15236            // System processes can do UI, and when they do we want to have
15237            // them trim their memory after the user leaves the UI.  To
15238            // facilitate this, here we need to determine whether or not it
15239            // is currently showing UI.
15240            app.systemNoUi = true;
15241            if (app == TOP_APP) {
15242                app.systemNoUi = false;
15243            } else if (activitiesSize > 0) {
15244                for (int j = 0; j < activitiesSize; j++) {
15245                    final ActivityRecord r = app.activities.get(j);
15246                    if (r.visible) {
15247                        app.systemNoUi = false;
15248                    }
15249                }
15250            }
15251            if (!app.systemNoUi) {
15252                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15253            }
15254            return (app.curAdj=app.maxAdj);
15255        }
15256
15257        app.systemNoUi = false;
15258
15259        // Determine the importance of the process, starting with most
15260        // important to least, and assign an appropriate OOM adjustment.
15261        int adj;
15262        int schedGroup;
15263        int procState;
15264        boolean foregroundActivities = false;
15265        BroadcastQueue queue;
15266        if (app == TOP_APP) {
15267            // The last app on the list is the foreground app.
15268            adj = ProcessList.FOREGROUND_APP_ADJ;
15269            schedGroup = Process.THREAD_GROUP_DEFAULT;
15270            app.adjType = "top-activity";
15271            foregroundActivities = true;
15272            procState = ActivityManager.PROCESS_STATE_TOP;
15273        } else if (app.instrumentationClass != null) {
15274            // Don't want to kill running instrumentation.
15275            adj = ProcessList.FOREGROUND_APP_ADJ;
15276            schedGroup = Process.THREAD_GROUP_DEFAULT;
15277            app.adjType = "instrumentation";
15278            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15279        } else if ((queue = isReceivingBroadcast(app)) != null) {
15280            // An app that is currently receiving a broadcast also
15281            // counts as being in the foreground for OOM killer purposes.
15282            // It's placed in a sched group based on the nature of the
15283            // broadcast as reflected by which queue it's active in.
15284            adj = ProcessList.FOREGROUND_APP_ADJ;
15285            schedGroup = (queue == mFgBroadcastQueue)
15286                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15287            app.adjType = "broadcast";
15288            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15289        } else if (app.executingServices.size() > 0) {
15290            // An app that is currently executing a service callback also
15291            // counts as being in the foreground.
15292            adj = ProcessList.FOREGROUND_APP_ADJ;
15293            schedGroup = app.execServicesFg ?
15294                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15295            app.adjType = "exec-service";
15296            procState = ActivityManager.PROCESS_STATE_SERVICE;
15297            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15298        } else {
15299            // As far as we know the process is empty.  We may change our mind later.
15300            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15301            // At this point we don't actually know the adjustment.  Use the cached adj
15302            // value that the caller wants us to.
15303            adj = cachedAdj;
15304            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15305            app.cached = true;
15306            app.empty = true;
15307            app.adjType = "cch-empty";
15308        }
15309
15310        // Examine all activities if not already foreground.
15311        if (!foregroundActivities && activitiesSize > 0) {
15312            for (int j = 0; j < activitiesSize; j++) {
15313                final ActivityRecord r = app.activities.get(j);
15314                if (r.app != app) {
15315                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15316                            + app + "?!?");
15317                    continue;
15318                }
15319                if (r.visible) {
15320                    // App has a visible activity; only upgrade adjustment.
15321                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15322                        adj = ProcessList.VISIBLE_APP_ADJ;
15323                        app.adjType = "visible";
15324                    }
15325                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15326                        procState = ActivityManager.PROCESS_STATE_TOP;
15327                    }
15328                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15329                    app.cached = false;
15330                    app.empty = false;
15331                    foregroundActivities = true;
15332                    break;
15333                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15334                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15335                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15336                        app.adjType = "pausing";
15337                    }
15338                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15339                        procState = ActivityManager.PROCESS_STATE_TOP;
15340                    }
15341                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15342                    app.cached = false;
15343                    app.empty = false;
15344                    foregroundActivities = true;
15345                } else if (r.state == ActivityState.STOPPING) {
15346                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15347                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15348                        app.adjType = "stopping";
15349                    }
15350                    // For the process state, we will at this point consider the
15351                    // process to be cached.  It will be cached either as an activity
15352                    // or empty depending on whether the activity is finishing.  We do
15353                    // this so that we can treat the process as cached for purposes of
15354                    // memory trimming (determing current memory level, trim command to
15355                    // send to process) since there can be an arbitrary number of stopping
15356                    // processes and they should soon all go into the cached state.
15357                    if (!r.finishing) {
15358                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15359                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15360                        }
15361                    }
15362                    app.cached = false;
15363                    app.empty = false;
15364                    foregroundActivities = true;
15365                } else {
15366                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15367                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15368                        app.adjType = "cch-act";
15369                    }
15370                }
15371            }
15372        }
15373
15374        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15375            if (app.foregroundServices) {
15376                // The user is aware of this app, so make it visible.
15377                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15378                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15379                app.cached = false;
15380                app.adjType = "fg-service";
15381                schedGroup = Process.THREAD_GROUP_DEFAULT;
15382            } else if (app.forcingToForeground != null) {
15383                // The user is aware of this app, so make it visible.
15384                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15385                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15386                app.cached = false;
15387                app.adjType = "force-fg";
15388                app.adjSource = app.forcingToForeground;
15389                schedGroup = Process.THREAD_GROUP_DEFAULT;
15390            }
15391        }
15392
15393        if (app == mHeavyWeightProcess) {
15394            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15395                // We don't want to kill the current heavy-weight process.
15396                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15397                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15398                app.cached = false;
15399                app.adjType = "heavy";
15400            }
15401            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15402                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15403            }
15404        }
15405
15406        if (app == mHomeProcess) {
15407            if (adj > ProcessList.HOME_APP_ADJ) {
15408                // This process is hosting what we currently consider to be the
15409                // home app, so we don't want to let it go into the background.
15410                adj = ProcessList.HOME_APP_ADJ;
15411                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15412                app.cached = false;
15413                app.adjType = "home";
15414            }
15415            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15416                procState = ActivityManager.PROCESS_STATE_HOME;
15417            }
15418        }
15419
15420        if (app == mPreviousProcess && app.activities.size() > 0) {
15421            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15422                // This was the previous process that showed UI to the user.
15423                // We want to try to keep it around more aggressively, to give
15424                // a good experience around switching between two apps.
15425                adj = ProcessList.PREVIOUS_APP_ADJ;
15426                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15427                app.cached = false;
15428                app.adjType = "previous";
15429            }
15430            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15431                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15432            }
15433        }
15434
15435        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15436                + " reason=" + app.adjType);
15437
15438        // By default, we use the computed adjustment.  It may be changed if
15439        // there are applications dependent on our services or providers, but
15440        // this gives us a baseline and makes sure we don't get into an
15441        // infinite recursion.
15442        app.adjSeq = mAdjSeq;
15443        app.curRawAdj = adj;
15444        app.hasStartedServices = false;
15445
15446        if (mBackupTarget != null && app == mBackupTarget.app) {
15447            // If possible we want to avoid killing apps while they're being backed up
15448            if (adj > ProcessList.BACKUP_APP_ADJ) {
15449                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15450                adj = ProcessList.BACKUP_APP_ADJ;
15451                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15452                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15453                }
15454                app.adjType = "backup";
15455                app.cached = false;
15456            }
15457            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15458                procState = ActivityManager.PROCESS_STATE_BACKUP;
15459            }
15460        }
15461
15462        boolean mayBeTop = false;
15463
15464        for (int is = app.services.size()-1;
15465                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15466                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15467                        || procState > ActivityManager.PROCESS_STATE_TOP);
15468                is--) {
15469            ServiceRecord s = app.services.valueAt(is);
15470            if (s.startRequested) {
15471                app.hasStartedServices = true;
15472                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15473                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15474                }
15475                if (app.hasShownUi && app != mHomeProcess) {
15476                    // If this process has shown some UI, let it immediately
15477                    // go to the LRU list because it may be pretty heavy with
15478                    // UI stuff.  We'll tag it with a label just to help
15479                    // debug and understand what is going on.
15480                    if (adj > ProcessList.SERVICE_ADJ) {
15481                        app.adjType = "cch-started-ui-services";
15482                    }
15483                } else {
15484                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15485                        // This service has seen some activity within
15486                        // recent memory, so we will keep its process ahead
15487                        // of the background processes.
15488                        if (adj > ProcessList.SERVICE_ADJ) {
15489                            adj = ProcessList.SERVICE_ADJ;
15490                            app.adjType = "started-services";
15491                            app.cached = false;
15492                        }
15493                    }
15494                    // If we have let the service slide into the background
15495                    // state, still have some text describing what it is doing
15496                    // even though the service no longer has an impact.
15497                    if (adj > ProcessList.SERVICE_ADJ) {
15498                        app.adjType = "cch-started-services";
15499                    }
15500                }
15501            }
15502            for (int conni = s.connections.size()-1;
15503                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15504                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15505                            || procState > ActivityManager.PROCESS_STATE_TOP);
15506                    conni--) {
15507                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15508                for (int i = 0;
15509                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15510                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15511                                || procState > ActivityManager.PROCESS_STATE_TOP);
15512                        i++) {
15513                    // XXX should compute this based on the max of
15514                    // all connected clients.
15515                    ConnectionRecord cr = clist.get(i);
15516                    if (cr.binding.client == app) {
15517                        // Binding to ourself is not interesting.
15518                        continue;
15519                    }
15520                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15521                        ProcessRecord client = cr.binding.client;
15522                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15523                                TOP_APP, doingAll, now);
15524                        int clientProcState = client.curProcState;
15525                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15526                            // If the other app is cached for any reason, for purposes here
15527                            // we are going to consider it empty.  The specific cached state
15528                            // doesn't propagate except under certain conditions.
15529                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15530                        }
15531                        String adjType = null;
15532                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15533                            // Not doing bind OOM management, so treat
15534                            // this guy more like a started service.
15535                            if (app.hasShownUi && app != mHomeProcess) {
15536                                // If this process has shown some UI, let it immediately
15537                                // go to the LRU list because it may be pretty heavy with
15538                                // UI stuff.  We'll tag it with a label just to help
15539                                // debug and understand what is going on.
15540                                if (adj > clientAdj) {
15541                                    adjType = "cch-bound-ui-services";
15542                                }
15543                                app.cached = false;
15544                                clientAdj = adj;
15545                                clientProcState = procState;
15546                            } else {
15547                                if (now >= (s.lastActivity
15548                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15549                                    // This service has not seen activity within
15550                                    // recent memory, so allow it to drop to the
15551                                    // LRU list if there is no other reason to keep
15552                                    // it around.  We'll also tag it with a label just
15553                                    // to help debug and undertand what is going on.
15554                                    if (adj > clientAdj) {
15555                                        adjType = "cch-bound-services";
15556                                    }
15557                                    clientAdj = adj;
15558                                }
15559                            }
15560                        }
15561                        if (adj > clientAdj) {
15562                            // If this process has recently shown UI, and
15563                            // the process that is binding to it is less
15564                            // important than being visible, then we don't
15565                            // care about the binding as much as we care
15566                            // about letting this process get into the LRU
15567                            // list to be killed and restarted if needed for
15568                            // memory.
15569                            if (app.hasShownUi && app != mHomeProcess
15570                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15571                                adjType = "cch-bound-ui-services";
15572                            } else {
15573                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15574                                        |Context.BIND_IMPORTANT)) != 0) {
15575                                    adj = clientAdj;
15576                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15577                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15578                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15579                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15580                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15581                                    adj = clientAdj;
15582                                } else {
15583                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15584                                        adj = ProcessList.VISIBLE_APP_ADJ;
15585                                    }
15586                                }
15587                                if (!client.cached) {
15588                                    app.cached = false;
15589                                }
15590                                adjType = "service";
15591                            }
15592                        }
15593                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15594                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15595                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15596                            }
15597                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15598                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15599                                    // Special handling of clients who are in the top state.
15600                                    // We *may* want to consider this process to be in the
15601                                    // top state as well, but only if there is not another
15602                                    // reason for it to be running.  Being on the top is a
15603                                    // special state, meaning you are specifically running
15604                                    // for the current top app.  If the process is already
15605                                    // running in the background for some other reason, it
15606                                    // is more important to continue considering it to be
15607                                    // in the background state.
15608                                    mayBeTop = true;
15609                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15610                                } else {
15611                                    // Special handling for above-top states (persistent
15612                                    // processes).  These should not bring the current process
15613                                    // into the top state, since they are not on top.  Instead
15614                                    // give them the best state after that.
15615                                    clientProcState =
15616                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15617                                }
15618                            }
15619                        } else {
15620                            if (clientProcState <
15621                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15622                                clientProcState =
15623                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15624                            }
15625                        }
15626                        if (procState > clientProcState) {
15627                            procState = clientProcState;
15628                        }
15629                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15630                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15631                            app.pendingUiClean = true;
15632                        }
15633                        if (adjType != null) {
15634                            app.adjType = adjType;
15635                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15636                                    .REASON_SERVICE_IN_USE;
15637                            app.adjSource = cr.binding.client;
15638                            app.adjSourceProcState = clientProcState;
15639                            app.adjTarget = s.name;
15640                        }
15641                    }
15642                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15643                        app.treatLikeActivity = true;
15644                    }
15645                    final ActivityRecord a = cr.activity;
15646                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15647                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15648                                (a.visible || a.state == ActivityState.RESUMED
15649                                 || a.state == ActivityState.PAUSING)) {
15650                            adj = ProcessList.FOREGROUND_APP_ADJ;
15651                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15652                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15653                            }
15654                            app.cached = false;
15655                            app.adjType = "service";
15656                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15657                                    .REASON_SERVICE_IN_USE;
15658                            app.adjSource = a;
15659                            app.adjSourceProcState = procState;
15660                            app.adjTarget = s.name;
15661                        }
15662                    }
15663                }
15664            }
15665        }
15666
15667        for (int provi = app.pubProviders.size()-1;
15668                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15669                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15670                        || procState > ActivityManager.PROCESS_STATE_TOP);
15671                provi--) {
15672            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15673            for (int i = cpr.connections.size()-1;
15674                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15675                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15676                            || procState > ActivityManager.PROCESS_STATE_TOP);
15677                    i--) {
15678                ContentProviderConnection conn = cpr.connections.get(i);
15679                ProcessRecord client = conn.client;
15680                if (client == app) {
15681                    // Being our own client is not interesting.
15682                    continue;
15683                }
15684                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15685                int clientProcState = client.curProcState;
15686                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15687                    // If the other app is cached for any reason, for purposes here
15688                    // we are going to consider it empty.
15689                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15690                }
15691                if (adj > clientAdj) {
15692                    if (app.hasShownUi && app != mHomeProcess
15693                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15694                        app.adjType = "cch-ui-provider";
15695                    } else {
15696                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15697                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15698                        app.adjType = "provider";
15699                    }
15700                    app.cached &= client.cached;
15701                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15702                            .REASON_PROVIDER_IN_USE;
15703                    app.adjSource = client;
15704                    app.adjSourceProcState = clientProcState;
15705                    app.adjTarget = cpr.name;
15706                }
15707                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15708                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15709                        // Special handling of clients who are in the top state.
15710                        // We *may* want to consider this process to be in the
15711                        // top state as well, but only if there is not another
15712                        // reason for it to be running.  Being on the top is a
15713                        // special state, meaning you are specifically running
15714                        // for the current top app.  If the process is already
15715                        // running in the background for some other reason, it
15716                        // is more important to continue considering it to be
15717                        // in the background state.
15718                        mayBeTop = true;
15719                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15720                    } else {
15721                        // Special handling for above-top states (persistent
15722                        // processes).  These should not bring the current process
15723                        // into the top state, since they are not on top.  Instead
15724                        // give them the best state after that.
15725                        clientProcState =
15726                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15727                    }
15728                }
15729                if (procState > clientProcState) {
15730                    procState = clientProcState;
15731                }
15732                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15733                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15734                }
15735            }
15736            // If the provider has external (non-framework) process
15737            // dependencies, ensure that its adjustment is at least
15738            // FOREGROUND_APP_ADJ.
15739            if (cpr.hasExternalProcessHandles()) {
15740                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15741                    adj = ProcessList.FOREGROUND_APP_ADJ;
15742                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15743                    app.cached = false;
15744                    app.adjType = "provider";
15745                    app.adjTarget = cpr.name;
15746                }
15747                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15748                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15749                }
15750            }
15751        }
15752
15753        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15754            // A client of one of our services or providers is in the top state.  We
15755            // *may* want to be in the top state, but not if we are already running in
15756            // the background for some other reason.  For the decision here, we are going
15757            // to pick out a few specific states that we want to remain in when a client
15758            // is top (states that tend to be longer-term) and otherwise allow it to go
15759            // to the top state.
15760            switch (procState) {
15761                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15762                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15763                case ActivityManager.PROCESS_STATE_SERVICE:
15764                    // These all are longer-term states, so pull them up to the top
15765                    // of the background states, but not all the way to the top state.
15766                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15767                    break;
15768                default:
15769                    // Otherwise, top is a better choice, so take it.
15770                    procState = ActivityManager.PROCESS_STATE_TOP;
15771                    break;
15772            }
15773        }
15774
15775        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15776            if (app.hasClientActivities) {
15777                // This is a cached process, but with client activities.  Mark it so.
15778                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15779                app.adjType = "cch-client-act";
15780            } else if (app.treatLikeActivity) {
15781                // This is a cached process, but somebody wants us to treat it like it has
15782                // an activity, okay!
15783                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15784                app.adjType = "cch-as-act";
15785            }
15786        }
15787
15788        if (adj == ProcessList.SERVICE_ADJ) {
15789            if (doingAll) {
15790                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15791                mNewNumServiceProcs++;
15792                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15793                if (!app.serviceb) {
15794                    // This service isn't far enough down on the LRU list to
15795                    // normally be a B service, but if we are low on RAM and it
15796                    // is large we want to force it down since we would prefer to
15797                    // keep launcher over it.
15798                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15799                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15800                        app.serviceHighRam = true;
15801                        app.serviceb = true;
15802                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15803                    } else {
15804                        mNewNumAServiceProcs++;
15805                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15806                    }
15807                } else {
15808                    app.serviceHighRam = false;
15809                }
15810            }
15811            if (app.serviceb) {
15812                adj = ProcessList.SERVICE_B_ADJ;
15813            }
15814        }
15815
15816        app.curRawAdj = adj;
15817
15818        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15819        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15820        if (adj > app.maxAdj) {
15821            adj = app.maxAdj;
15822            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15823                schedGroup = Process.THREAD_GROUP_DEFAULT;
15824            }
15825        }
15826
15827        // Do final modification to adj.  Everything we do between here and applying
15828        // the final setAdj must be done in this function, because we will also use
15829        // it when computing the final cached adj later.  Note that we don't need to
15830        // worry about this for max adj above, since max adj will always be used to
15831        // keep it out of the cached vaues.
15832        app.curAdj = app.modifyRawOomAdj(adj);
15833        app.curSchedGroup = schedGroup;
15834        app.curProcState = procState;
15835        app.foregroundActivities = foregroundActivities;
15836
15837        return app.curRawAdj;
15838    }
15839
15840    /**
15841     * Schedule PSS collection of a process.
15842     */
15843    void requestPssLocked(ProcessRecord proc, int procState) {
15844        if (mPendingPssProcesses.contains(proc)) {
15845            return;
15846        }
15847        if (mPendingPssProcesses.size() == 0) {
15848            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15849        }
15850        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15851        proc.pssProcState = procState;
15852        mPendingPssProcesses.add(proc);
15853    }
15854
15855    /**
15856     * Schedule PSS collection of all processes.
15857     */
15858    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15859        if (!always) {
15860            if (now < (mLastFullPssTime +
15861                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15862                return;
15863            }
15864        }
15865        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15866        mLastFullPssTime = now;
15867        mFullPssPending = true;
15868        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15869        mPendingPssProcesses.clear();
15870        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15871            ProcessRecord app = mLruProcesses.get(i);
15872            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15873                app.pssProcState = app.setProcState;
15874                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15875                        isSleeping(), now);
15876                mPendingPssProcesses.add(app);
15877            }
15878        }
15879        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15880    }
15881
15882    /**
15883     * Ask a given process to GC right now.
15884     */
15885    final void performAppGcLocked(ProcessRecord app) {
15886        try {
15887            app.lastRequestedGc = SystemClock.uptimeMillis();
15888            if (app.thread != null) {
15889                if (app.reportLowMemory) {
15890                    app.reportLowMemory = false;
15891                    app.thread.scheduleLowMemory();
15892                } else {
15893                    app.thread.processInBackground();
15894                }
15895            }
15896        } catch (Exception e) {
15897            // whatever.
15898        }
15899    }
15900
15901    /**
15902     * Returns true if things are idle enough to perform GCs.
15903     */
15904    private final boolean canGcNowLocked() {
15905        boolean processingBroadcasts = false;
15906        for (BroadcastQueue q : mBroadcastQueues) {
15907            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15908                processingBroadcasts = true;
15909            }
15910        }
15911        return !processingBroadcasts
15912                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15913    }
15914
15915    /**
15916     * Perform GCs on all processes that are waiting for it, but only
15917     * if things are idle.
15918     */
15919    final void performAppGcsLocked() {
15920        final int N = mProcessesToGc.size();
15921        if (N <= 0) {
15922            return;
15923        }
15924        if (canGcNowLocked()) {
15925            while (mProcessesToGc.size() > 0) {
15926                ProcessRecord proc = mProcessesToGc.remove(0);
15927                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15928                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15929                            <= SystemClock.uptimeMillis()) {
15930                        // To avoid spamming the system, we will GC processes one
15931                        // at a time, waiting a few seconds between each.
15932                        performAppGcLocked(proc);
15933                        scheduleAppGcsLocked();
15934                        return;
15935                    } else {
15936                        // It hasn't been long enough since we last GCed this
15937                        // process...  put it in the list to wait for its time.
15938                        addProcessToGcListLocked(proc);
15939                        break;
15940                    }
15941                }
15942            }
15943
15944            scheduleAppGcsLocked();
15945        }
15946    }
15947
15948    /**
15949     * If all looks good, perform GCs on all processes waiting for them.
15950     */
15951    final void performAppGcsIfAppropriateLocked() {
15952        if (canGcNowLocked()) {
15953            performAppGcsLocked();
15954            return;
15955        }
15956        // Still not idle, wait some more.
15957        scheduleAppGcsLocked();
15958    }
15959
15960    /**
15961     * Schedule the execution of all pending app GCs.
15962     */
15963    final void scheduleAppGcsLocked() {
15964        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15965
15966        if (mProcessesToGc.size() > 0) {
15967            // Schedule a GC for the time to the next process.
15968            ProcessRecord proc = mProcessesToGc.get(0);
15969            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15970
15971            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15972            long now = SystemClock.uptimeMillis();
15973            if (when < (now+GC_TIMEOUT)) {
15974                when = now + GC_TIMEOUT;
15975            }
15976            mHandler.sendMessageAtTime(msg, when);
15977        }
15978    }
15979
15980    /**
15981     * Add a process to the array of processes waiting to be GCed.  Keeps the
15982     * list in sorted order by the last GC time.  The process can't already be
15983     * on the list.
15984     */
15985    final void addProcessToGcListLocked(ProcessRecord proc) {
15986        boolean added = false;
15987        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15988            if (mProcessesToGc.get(i).lastRequestedGc <
15989                    proc.lastRequestedGc) {
15990                added = true;
15991                mProcessesToGc.add(i+1, proc);
15992                break;
15993            }
15994        }
15995        if (!added) {
15996            mProcessesToGc.add(0, proc);
15997        }
15998    }
15999
16000    /**
16001     * Set up to ask a process to GC itself.  This will either do it
16002     * immediately, or put it on the list of processes to gc the next
16003     * time things are idle.
16004     */
16005    final void scheduleAppGcLocked(ProcessRecord app) {
16006        long now = SystemClock.uptimeMillis();
16007        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16008            return;
16009        }
16010        if (!mProcessesToGc.contains(app)) {
16011            addProcessToGcListLocked(app);
16012            scheduleAppGcsLocked();
16013        }
16014    }
16015
16016    final void checkExcessivePowerUsageLocked(boolean doKills) {
16017        updateCpuStatsNow();
16018
16019        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16020        boolean doWakeKills = doKills;
16021        boolean doCpuKills = doKills;
16022        if (mLastPowerCheckRealtime == 0) {
16023            doWakeKills = false;
16024        }
16025        if (mLastPowerCheckUptime == 0) {
16026            doCpuKills = false;
16027        }
16028        if (stats.isScreenOn()) {
16029            doWakeKills = false;
16030        }
16031        final long curRealtime = SystemClock.elapsedRealtime();
16032        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16033        final long curUptime = SystemClock.uptimeMillis();
16034        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16035        mLastPowerCheckRealtime = curRealtime;
16036        mLastPowerCheckUptime = curUptime;
16037        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16038            doWakeKills = false;
16039        }
16040        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16041            doCpuKills = false;
16042        }
16043        int i = mLruProcesses.size();
16044        while (i > 0) {
16045            i--;
16046            ProcessRecord app = mLruProcesses.get(i);
16047            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16048                long wtime;
16049                synchronized (stats) {
16050                    wtime = stats.getProcessWakeTime(app.info.uid,
16051                            app.pid, curRealtime);
16052                }
16053                long wtimeUsed = wtime - app.lastWakeTime;
16054                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16055                if (DEBUG_POWER) {
16056                    StringBuilder sb = new StringBuilder(128);
16057                    sb.append("Wake for ");
16058                    app.toShortString(sb);
16059                    sb.append(": over ");
16060                    TimeUtils.formatDuration(realtimeSince, sb);
16061                    sb.append(" used ");
16062                    TimeUtils.formatDuration(wtimeUsed, sb);
16063                    sb.append(" (");
16064                    sb.append((wtimeUsed*100)/realtimeSince);
16065                    sb.append("%)");
16066                    Slog.i(TAG, sb.toString());
16067                    sb.setLength(0);
16068                    sb.append("CPU for ");
16069                    app.toShortString(sb);
16070                    sb.append(": over ");
16071                    TimeUtils.formatDuration(uptimeSince, sb);
16072                    sb.append(" used ");
16073                    TimeUtils.formatDuration(cputimeUsed, sb);
16074                    sb.append(" (");
16075                    sb.append((cputimeUsed*100)/uptimeSince);
16076                    sb.append("%)");
16077                    Slog.i(TAG, sb.toString());
16078                }
16079                // If a process has held a wake lock for more
16080                // than 50% of the time during this period,
16081                // that sounds bad.  Kill!
16082                if (doWakeKills && realtimeSince > 0
16083                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16084                    synchronized (stats) {
16085                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16086                                realtimeSince, wtimeUsed);
16087                    }
16088                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16089                            + " during " + realtimeSince);
16090                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16091                } else if (doCpuKills && uptimeSince > 0
16092                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16093                    synchronized (stats) {
16094                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16095                                uptimeSince, cputimeUsed);
16096                    }
16097                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16098                            + " during " + uptimeSince);
16099                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16100                } else {
16101                    app.lastWakeTime = wtime;
16102                    app.lastCpuTime = app.curCpuTime;
16103                }
16104            }
16105        }
16106    }
16107
16108    private final boolean applyOomAdjLocked(ProcessRecord app,
16109            ProcessRecord TOP_APP, boolean doingAll, long now) {
16110        boolean success = true;
16111
16112        if (app.curRawAdj != app.setRawAdj) {
16113            app.setRawAdj = app.curRawAdj;
16114        }
16115
16116        int changes = 0;
16117
16118        if (app.curAdj != app.setAdj) {
16119            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16120            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16121                TAG, "Set " + app.pid + " " + app.processName +
16122                " adj " + app.curAdj + ": " + app.adjType);
16123            app.setAdj = app.curAdj;
16124        }
16125
16126        if (app.setSchedGroup != app.curSchedGroup) {
16127            app.setSchedGroup = app.curSchedGroup;
16128            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16129                    "Setting process group of " + app.processName
16130                    + " to " + app.curSchedGroup);
16131            if (app.waitingToKill != null &&
16132                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16133                killUnneededProcessLocked(app, app.waitingToKill);
16134                success = false;
16135            } else {
16136                if (true) {
16137                    long oldId = Binder.clearCallingIdentity();
16138                    try {
16139                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16140                    } catch (Exception e) {
16141                        Slog.w(TAG, "Failed setting process group of " + app.pid
16142                                + " to " + app.curSchedGroup);
16143                        e.printStackTrace();
16144                    } finally {
16145                        Binder.restoreCallingIdentity(oldId);
16146                    }
16147                } else {
16148                    if (app.thread != null) {
16149                        try {
16150                            app.thread.setSchedulingGroup(app.curSchedGroup);
16151                        } catch (RemoteException e) {
16152                        }
16153                    }
16154                }
16155                Process.setSwappiness(app.pid,
16156                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16157            }
16158        }
16159        if (app.repForegroundActivities != app.foregroundActivities) {
16160            app.repForegroundActivities = app.foregroundActivities;
16161            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16162        }
16163        if (app.repProcState != app.curProcState) {
16164            app.repProcState = app.curProcState;
16165            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16166            if (app.thread != null) {
16167                try {
16168                    if (false) {
16169                        //RuntimeException h = new RuntimeException("here");
16170                        Slog.i(TAG, "Sending new process state " + app.repProcState
16171                                + " to " + app /*, h*/);
16172                    }
16173                    app.thread.setProcessState(app.repProcState);
16174                } catch (RemoteException e) {
16175                }
16176            }
16177        }
16178        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16179                app.setProcState)) {
16180            app.lastStateTime = now;
16181            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16182                    isSleeping(), now);
16183            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16184                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16185                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16186                    + (app.nextPssTime-now) + ": " + app);
16187        } else {
16188            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16189                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16190                requestPssLocked(app, app.setProcState);
16191                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16192                        isSleeping(), now);
16193            } else if (false && DEBUG_PSS) {
16194                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16195            }
16196        }
16197        if (app.setProcState != app.curProcState) {
16198            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16199                    "Proc state change of " + app.processName
16200                    + " to " + app.curProcState);
16201            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16202            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16203            if (setImportant && !curImportant) {
16204                // This app is no longer something we consider important enough to allow to
16205                // use arbitrary amounts of battery power.  Note
16206                // its current wake lock time to later know to kill it if
16207                // it is not behaving well.
16208                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16209                synchronized (stats) {
16210                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16211                            app.pid, SystemClock.elapsedRealtime());
16212                }
16213                app.lastCpuTime = app.curCpuTime;
16214
16215            }
16216            app.setProcState = app.curProcState;
16217            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16218                app.notCachedSinceIdle = false;
16219            }
16220            if (!doingAll) {
16221                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16222            } else {
16223                app.procStateChanged = true;
16224            }
16225        }
16226
16227        if (changes != 0) {
16228            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16229            int i = mPendingProcessChanges.size()-1;
16230            ProcessChangeItem item = null;
16231            while (i >= 0) {
16232                item = mPendingProcessChanges.get(i);
16233                if (item.pid == app.pid) {
16234                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16235                    break;
16236                }
16237                i--;
16238            }
16239            if (i < 0) {
16240                // No existing item in pending changes; need a new one.
16241                final int NA = mAvailProcessChanges.size();
16242                if (NA > 0) {
16243                    item = mAvailProcessChanges.remove(NA-1);
16244                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16245                } else {
16246                    item = new ProcessChangeItem();
16247                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16248                }
16249                item.changes = 0;
16250                item.pid = app.pid;
16251                item.uid = app.info.uid;
16252                if (mPendingProcessChanges.size() == 0) {
16253                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16254                            "*** Enqueueing dispatch processes changed!");
16255                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16256                }
16257                mPendingProcessChanges.add(item);
16258            }
16259            item.changes |= changes;
16260            item.processState = app.repProcState;
16261            item.foregroundActivities = app.repForegroundActivities;
16262            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16263                    + Integer.toHexString(System.identityHashCode(item))
16264                    + " " + app.toShortString() + ": changes=" + item.changes
16265                    + " procState=" + item.processState
16266                    + " foreground=" + item.foregroundActivities
16267                    + " type=" + app.adjType + " source=" + app.adjSource
16268                    + " target=" + app.adjTarget);
16269        }
16270
16271        return success;
16272    }
16273
16274    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16275        if (proc.thread != null) {
16276            if (proc.baseProcessTracker != null) {
16277                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16278            }
16279            if (proc.repProcState >= 0) {
16280                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16281                        proc.repProcState);
16282            }
16283        }
16284    }
16285
16286    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16287            ProcessRecord TOP_APP, boolean doingAll, long now) {
16288        if (app.thread == null) {
16289            return false;
16290        }
16291
16292        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16293
16294        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16295    }
16296
16297    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16298            boolean oomAdj) {
16299        if (isForeground != proc.foregroundServices) {
16300            proc.foregroundServices = isForeground;
16301            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16302                    proc.info.uid);
16303            if (isForeground) {
16304                if (curProcs == null) {
16305                    curProcs = new ArrayList<ProcessRecord>();
16306                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16307                }
16308                if (!curProcs.contains(proc)) {
16309                    curProcs.add(proc);
16310                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16311                            proc.info.packageName, proc.info.uid);
16312                }
16313            } else {
16314                if (curProcs != null) {
16315                    if (curProcs.remove(proc)) {
16316                        mBatteryStatsService.noteEvent(
16317                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16318                                proc.info.packageName, proc.info.uid);
16319                        if (curProcs.size() <= 0) {
16320                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16321                        }
16322                    }
16323                }
16324            }
16325            if (oomAdj) {
16326                updateOomAdjLocked();
16327            }
16328        }
16329    }
16330
16331    private final ActivityRecord resumedAppLocked() {
16332        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16333        String pkg;
16334        int uid;
16335        if (act != null) {
16336            pkg = act.packageName;
16337            uid = act.info.applicationInfo.uid;
16338        } else {
16339            pkg = null;
16340            uid = -1;
16341        }
16342        // Has the UID or resumed package name changed?
16343        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16344                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16345            if (mCurResumedPackage != null) {
16346                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16347                        mCurResumedPackage, mCurResumedUid);
16348            }
16349            mCurResumedPackage = pkg;
16350            mCurResumedUid = uid;
16351            if (mCurResumedPackage != null) {
16352                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16353                        mCurResumedPackage, mCurResumedUid);
16354            }
16355        }
16356        return act;
16357    }
16358
16359    final boolean updateOomAdjLocked(ProcessRecord app) {
16360        final ActivityRecord TOP_ACT = resumedAppLocked();
16361        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16362        final boolean wasCached = app.cached;
16363
16364        mAdjSeq++;
16365
16366        // This is the desired cached adjusment we want to tell it to use.
16367        // If our app is currently cached, we know it, and that is it.  Otherwise,
16368        // we don't know it yet, and it needs to now be cached we will then
16369        // need to do a complete oom adj.
16370        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16371                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16372        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16373                SystemClock.uptimeMillis());
16374        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16375            // Changed to/from cached state, so apps after it in the LRU
16376            // list may also be changed.
16377            updateOomAdjLocked();
16378        }
16379        return success;
16380    }
16381
16382    final void updateOomAdjLocked() {
16383        final ActivityRecord TOP_ACT = resumedAppLocked();
16384        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16385        final long now = SystemClock.uptimeMillis();
16386        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16387        final int N = mLruProcesses.size();
16388
16389        if (false) {
16390            RuntimeException e = new RuntimeException();
16391            e.fillInStackTrace();
16392            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16393        }
16394
16395        mAdjSeq++;
16396        mNewNumServiceProcs = 0;
16397        mNewNumAServiceProcs = 0;
16398
16399        final int emptyProcessLimit;
16400        final int cachedProcessLimit;
16401        if (mProcessLimit <= 0) {
16402            emptyProcessLimit = cachedProcessLimit = 0;
16403        } else if (mProcessLimit == 1) {
16404            emptyProcessLimit = 1;
16405            cachedProcessLimit = 0;
16406        } else {
16407            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16408            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16409        }
16410
16411        // Let's determine how many processes we have running vs.
16412        // how many slots we have for background processes; we may want
16413        // to put multiple processes in a slot of there are enough of
16414        // them.
16415        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16416                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16417        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16418        if (numEmptyProcs > cachedProcessLimit) {
16419            // If there are more empty processes than our limit on cached
16420            // processes, then use the cached process limit for the factor.
16421            // This ensures that the really old empty processes get pushed
16422            // down to the bottom, so if we are running low on memory we will
16423            // have a better chance at keeping around more cached processes
16424            // instead of a gazillion empty processes.
16425            numEmptyProcs = cachedProcessLimit;
16426        }
16427        int emptyFactor = numEmptyProcs/numSlots;
16428        if (emptyFactor < 1) emptyFactor = 1;
16429        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16430        if (cachedFactor < 1) cachedFactor = 1;
16431        int stepCached = 0;
16432        int stepEmpty = 0;
16433        int numCached = 0;
16434        int numEmpty = 0;
16435        int numTrimming = 0;
16436
16437        mNumNonCachedProcs = 0;
16438        mNumCachedHiddenProcs = 0;
16439
16440        // First update the OOM adjustment for each of the
16441        // application processes based on their current state.
16442        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16443        int nextCachedAdj = curCachedAdj+1;
16444        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16445        int nextEmptyAdj = curEmptyAdj+2;
16446        for (int i=N-1; i>=0; i--) {
16447            ProcessRecord app = mLruProcesses.get(i);
16448            if (!app.killedByAm && app.thread != null) {
16449                app.procStateChanged = false;
16450                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16451
16452                // If we haven't yet assigned the final cached adj
16453                // to the process, do that now.
16454                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16455                    switch (app.curProcState) {
16456                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16457                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16458                            // This process is a cached process holding activities...
16459                            // assign it the next cached value for that type, and then
16460                            // step that cached level.
16461                            app.curRawAdj = curCachedAdj;
16462                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16463                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16464                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16465                                    + ")");
16466                            if (curCachedAdj != nextCachedAdj) {
16467                                stepCached++;
16468                                if (stepCached >= cachedFactor) {
16469                                    stepCached = 0;
16470                                    curCachedAdj = nextCachedAdj;
16471                                    nextCachedAdj += 2;
16472                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16473                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16474                                    }
16475                                }
16476                            }
16477                            break;
16478                        default:
16479                            // For everything else, assign next empty cached process
16480                            // level and bump that up.  Note that this means that
16481                            // long-running services that have dropped down to the
16482                            // cached level will be treated as empty (since their process
16483                            // state is still as a service), which is what we want.
16484                            app.curRawAdj = curEmptyAdj;
16485                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16486                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16487                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16488                                    + ")");
16489                            if (curEmptyAdj != nextEmptyAdj) {
16490                                stepEmpty++;
16491                                if (stepEmpty >= emptyFactor) {
16492                                    stepEmpty = 0;
16493                                    curEmptyAdj = nextEmptyAdj;
16494                                    nextEmptyAdj += 2;
16495                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16496                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16497                                    }
16498                                }
16499                            }
16500                            break;
16501                    }
16502                }
16503
16504                applyOomAdjLocked(app, TOP_APP, true, now);
16505
16506                // Count the number of process types.
16507                switch (app.curProcState) {
16508                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16509                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16510                        mNumCachedHiddenProcs++;
16511                        numCached++;
16512                        if (numCached > cachedProcessLimit) {
16513                            killUnneededProcessLocked(app, "cached #" + numCached);
16514                        }
16515                        break;
16516                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16517                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16518                                && app.lastActivityTime < oldTime) {
16519                            killUnneededProcessLocked(app, "empty for "
16520                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16521                                    / 1000) + "s");
16522                        } else {
16523                            numEmpty++;
16524                            if (numEmpty > emptyProcessLimit) {
16525                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16526                            }
16527                        }
16528                        break;
16529                    default:
16530                        mNumNonCachedProcs++;
16531                        break;
16532                }
16533
16534                if (app.isolated && app.services.size() <= 0) {
16535                    // If this is an isolated process, and there are no
16536                    // services running in it, then the process is no longer
16537                    // needed.  We agressively kill these because we can by
16538                    // definition not re-use the same process again, and it is
16539                    // good to avoid having whatever code was running in them
16540                    // left sitting around after no longer needed.
16541                    killUnneededProcessLocked(app, "isolated not needed");
16542                }
16543
16544                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16545                        && !app.killedByAm) {
16546                    numTrimming++;
16547                }
16548            }
16549        }
16550
16551        mNumServiceProcs = mNewNumServiceProcs;
16552
16553        // Now determine the memory trimming level of background processes.
16554        // Unfortunately we need to start at the back of the list to do this
16555        // properly.  We only do this if the number of background apps we
16556        // are managing to keep around is less than half the maximum we desire;
16557        // if we are keeping a good number around, we'll let them use whatever
16558        // memory they want.
16559        final int numCachedAndEmpty = numCached + numEmpty;
16560        int memFactor;
16561        if (numCached <= ProcessList.TRIM_CACHED_APPS
16562                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16563            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16564                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16565            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16566                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16567            } else {
16568                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16569            }
16570        } else {
16571            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16572        }
16573        // We always allow the memory level to go up (better).  We only allow it to go
16574        // down if we are in a state where that is allowed, *and* the total number of processes
16575        // has gone down since last time.
16576        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16577                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16578                + " last=" + mLastNumProcesses);
16579        if (memFactor > mLastMemoryLevel) {
16580            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16581                memFactor = mLastMemoryLevel;
16582                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16583            }
16584        }
16585        mLastMemoryLevel = memFactor;
16586        mLastNumProcesses = mLruProcesses.size();
16587        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16588        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16589        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16590            if (mLowRamStartTime == 0) {
16591                mLowRamStartTime = now;
16592            }
16593            int step = 0;
16594            int fgTrimLevel;
16595            switch (memFactor) {
16596                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16597                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16598                    break;
16599                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16600                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16601                    break;
16602                default:
16603                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16604                    break;
16605            }
16606            int factor = numTrimming/3;
16607            int minFactor = 2;
16608            if (mHomeProcess != null) minFactor++;
16609            if (mPreviousProcess != null) minFactor++;
16610            if (factor < minFactor) factor = minFactor;
16611            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16612            for (int i=N-1; i>=0; i--) {
16613                ProcessRecord app = mLruProcesses.get(i);
16614                if (allChanged || app.procStateChanged) {
16615                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16616                    app.procStateChanged = false;
16617                }
16618                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16619                        && !app.killedByAm) {
16620                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16621                        try {
16622                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16623                                    "Trimming memory of " + app.processName
16624                                    + " to " + curLevel);
16625                            app.thread.scheduleTrimMemory(curLevel);
16626                        } catch (RemoteException e) {
16627                        }
16628                        if (false) {
16629                            // For now we won't do this; our memory trimming seems
16630                            // to be good enough at this point that destroying
16631                            // activities causes more harm than good.
16632                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16633                                    && app != mHomeProcess && app != mPreviousProcess) {
16634                                // Need to do this on its own message because the stack may not
16635                                // be in a consistent state at this point.
16636                                // For these apps we will also finish their activities
16637                                // to help them free memory.
16638                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16639                            }
16640                        }
16641                    }
16642                    app.trimMemoryLevel = curLevel;
16643                    step++;
16644                    if (step >= factor) {
16645                        step = 0;
16646                        switch (curLevel) {
16647                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16648                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16649                                break;
16650                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16651                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16652                                break;
16653                        }
16654                    }
16655                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16656                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16657                            && app.thread != null) {
16658                        try {
16659                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16660                                    "Trimming memory of heavy-weight " + app.processName
16661                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16662                            app.thread.scheduleTrimMemory(
16663                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16664                        } catch (RemoteException e) {
16665                        }
16666                    }
16667                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16668                } else {
16669                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16670                            || app.systemNoUi) && app.pendingUiClean) {
16671                        // If this application is now in the background and it
16672                        // had done UI, then give it the special trim level to
16673                        // have it free UI resources.
16674                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16675                        if (app.trimMemoryLevel < level && app.thread != null) {
16676                            try {
16677                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16678                                        "Trimming memory of bg-ui " + app.processName
16679                                        + " to " + level);
16680                                app.thread.scheduleTrimMemory(level);
16681                            } catch (RemoteException e) {
16682                            }
16683                        }
16684                        app.pendingUiClean = false;
16685                    }
16686                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16687                        try {
16688                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16689                                    "Trimming memory of fg " + app.processName
16690                                    + " to " + fgTrimLevel);
16691                            app.thread.scheduleTrimMemory(fgTrimLevel);
16692                        } catch (RemoteException e) {
16693                        }
16694                    }
16695                    app.trimMemoryLevel = fgTrimLevel;
16696                }
16697            }
16698        } else {
16699            if (mLowRamStartTime != 0) {
16700                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16701                mLowRamStartTime = 0;
16702            }
16703            for (int i=N-1; i>=0; i--) {
16704                ProcessRecord app = mLruProcesses.get(i);
16705                if (allChanged || app.procStateChanged) {
16706                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16707                    app.procStateChanged = false;
16708                }
16709                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16710                        || app.systemNoUi) && app.pendingUiClean) {
16711                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16712                            && app.thread != null) {
16713                        try {
16714                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16715                                    "Trimming memory of ui hidden " + app.processName
16716                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16717                            app.thread.scheduleTrimMemory(
16718                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16719                        } catch (RemoteException e) {
16720                        }
16721                    }
16722                    app.pendingUiClean = false;
16723                }
16724                app.trimMemoryLevel = 0;
16725            }
16726        }
16727
16728        if (mAlwaysFinishActivities) {
16729            // Need to do this on its own message because the stack may not
16730            // be in a consistent state at this point.
16731            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16732        }
16733
16734        if (allChanged) {
16735            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16736        }
16737
16738        if (mProcessStats.shouldWriteNowLocked(now)) {
16739            mHandler.post(new Runnable() {
16740                @Override public void run() {
16741                    synchronized (ActivityManagerService.this) {
16742                        mProcessStats.writeStateAsyncLocked();
16743                    }
16744                }
16745            });
16746        }
16747
16748        if (DEBUG_OOM_ADJ) {
16749            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16750        }
16751    }
16752
16753    final void trimApplications() {
16754        synchronized (this) {
16755            int i;
16756
16757            // First remove any unused application processes whose package
16758            // has been removed.
16759            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16760                final ProcessRecord app = mRemovedProcesses.get(i);
16761                if (app.activities.size() == 0
16762                        && app.curReceiver == null && app.services.size() == 0) {
16763                    Slog.i(
16764                        TAG, "Exiting empty application process "
16765                        + app.processName + " ("
16766                        + (app.thread != null ? app.thread.asBinder() : null)
16767                        + ")\n");
16768                    if (app.pid > 0 && app.pid != MY_PID) {
16769                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16770                                app.processName, app.setAdj, "empty");
16771                        app.killedByAm = true;
16772                        Process.killProcessQuiet(app.pid);
16773                        Process.killProcessGroup(app.info.uid, app.pid);
16774                    } else {
16775                        try {
16776                            app.thread.scheduleExit();
16777                        } catch (Exception e) {
16778                            // Ignore exceptions.
16779                        }
16780                    }
16781                    cleanUpApplicationRecordLocked(app, false, true, -1);
16782                    mRemovedProcesses.remove(i);
16783
16784                    if (app.persistent) {
16785                        addAppLocked(app.info, false, null /* ABI override */);
16786                    }
16787                }
16788            }
16789
16790            // Now update the oom adj for all processes.
16791            updateOomAdjLocked();
16792        }
16793    }
16794
16795    /** This method sends the specified signal to each of the persistent apps */
16796    public void signalPersistentProcesses(int sig) throws RemoteException {
16797        if (sig != Process.SIGNAL_USR1) {
16798            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16799        }
16800
16801        synchronized (this) {
16802            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16803                    != PackageManager.PERMISSION_GRANTED) {
16804                throw new SecurityException("Requires permission "
16805                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16806            }
16807
16808            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16809                ProcessRecord r = mLruProcesses.get(i);
16810                if (r.thread != null && r.persistent) {
16811                    Process.sendSignal(r.pid, sig);
16812                }
16813            }
16814        }
16815    }
16816
16817    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16818        if (proc == null || proc == mProfileProc) {
16819            proc = mProfileProc;
16820            path = mProfileFile;
16821            profileType = mProfileType;
16822            clearProfilerLocked();
16823        }
16824        if (proc == null) {
16825            return;
16826        }
16827        try {
16828            proc.thread.profilerControl(false, path, null, profileType);
16829        } catch (RemoteException e) {
16830            throw new IllegalStateException("Process disappeared");
16831        }
16832    }
16833
16834    private void clearProfilerLocked() {
16835        if (mProfileFd != null) {
16836            try {
16837                mProfileFd.close();
16838            } catch (IOException e) {
16839            }
16840        }
16841        mProfileApp = null;
16842        mProfileProc = null;
16843        mProfileFile = null;
16844        mProfileType = 0;
16845        mAutoStopProfiler = false;
16846    }
16847
16848    public boolean profileControl(String process, int userId, boolean start,
16849            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16850
16851        try {
16852            synchronized (this) {
16853                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16854                // its own permission.
16855                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16856                        != PackageManager.PERMISSION_GRANTED) {
16857                    throw new SecurityException("Requires permission "
16858                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16859                }
16860
16861                if (start && fd == null) {
16862                    throw new IllegalArgumentException("null fd");
16863                }
16864
16865                ProcessRecord proc = null;
16866                if (process != null) {
16867                    proc = findProcessLocked(process, userId, "profileControl");
16868                }
16869
16870                if (start && (proc == null || proc.thread == null)) {
16871                    throw new IllegalArgumentException("Unknown process: " + process);
16872                }
16873
16874                if (start) {
16875                    stopProfilerLocked(null, null, 0);
16876                    setProfileApp(proc.info, proc.processName, path, fd, false);
16877                    mProfileProc = proc;
16878                    mProfileType = profileType;
16879                    try {
16880                        fd = fd.dup();
16881                    } catch (IOException e) {
16882                        fd = null;
16883                    }
16884                    proc.thread.profilerControl(start, path, fd, profileType);
16885                    fd = null;
16886                    mProfileFd = null;
16887                } else {
16888                    stopProfilerLocked(proc, path, profileType);
16889                    if (fd != null) {
16890                        try {
16891                            fd.close();
16892                        } catch (IOException e) {
16893                        }
16894                    }
16895                }
16896
16897                return true;
16898            }
16899        } catch (RemoteException e) {
16900            throw new IllegalStateException("Process disappeared");
16901        } finally {
16902            if (fd != null) {
16903                try {
16904                    fd.close();
16905                } catch (IOException e) {
16906                }
16907            }
16908        }
16909    }
16910
16911    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16912        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16913                userId, true, ALLOW_FULL_ONLY, callName, null);
16914        ProcessRecord proc = null;
16915        try {
16916            int pid = Integer.parseInt(process);
16917            synchronized (mPidsSelfLocked) {
16918                proc = mPidsSelfLocked.get(pid);
16919            }
16920        } catch (NumberFormatException e) {
16921        }
16922
16923        if (proc == null) {
16924            ArrayMap<String, SparseArray<ProcessRecord>> all
16925                    = mProcessNames.getMap();
16926            SparseArray<ProcessRecord> procs = all.get(process);
16927            if (procs != null && procs.size() > 0) {
16928                proc = procs.valueAt(0);
16929                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16930                    for (int i=1; i<procs.size(); i++) {
16931                        ProcessRecord thisProc = procs.valueAt(i);
16932                        if (thisProc.userId == userId) {
16933                            proc = thisProc;
16934                            break;
16935                        }
16936                    }
16937                }
16938            }
16939        }
16940
16941        return proc;
16942    }
16943
16944    public boolean dumpHeap(String process, int userId, boolean managed,
16945            String path, ParcelFileDescriptor fd) throws RemoteException {
16946
16947        try {
16948            synchronized (this) {
16949                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16950                // its own permission (same as profileControl).
16951                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16952                        != PackageManager.PERMISSION_GRANTED) {
16953                    throw new SecurityException("Requires permission "
16954                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16955                }
16956
16957                if (fd == null) {
16958                    throw new IllegalArgumentException("null fd");
16959                }
16960
16961                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16962                if (proc == null || proc.thread == null) {
16963                    throw new IllegalArgumentException("Unknown process: " + process);
16964                }
16965
16966                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16967                if (!isDebuggable) {
16968                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16969                        throw new SecurityException("Process not debuggable: " + proc);
16970                    }
16971                }
16972
16973                proc.thread.dumpHeap(managed, path, fd);
16974                fd = null;
16975                return true;
16976            }
16977        } catch (RemoteException e) {
16978            throw new IllegalStateException("Process disappeared");
16979        } finally {
16980            if (fd != null) {
16981                try {
16982                    fd.close();
16983                } catch (IOException e) {
16984                }
16985            }
16986        }
16987    }
16988
16989    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16990    public void monitor() {
16991        synchronized (this) { }
16992    }
16993
16994    void onCoreSettingsChange(Bundle settings) {
16995        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16996            ProcessRecord processRecord = mLruProcesses.get(i);
16997            try {
16998                if (processRecord.thread != null) {
16999                    processRecord.thread.setCoreSettings(settings);
17000                }
17001            } catch (RemoteException re) {
17002                /* ignore */
17003            }
17004        }
17005    }
17006
17007    // Multi-user methods
17008
17009    /**
17010     * Start user, if its not already running, but don't bring it to foreground.
17011     */
17012    @Override
17013    public boolean startUserInBackground(final int userId) {
17014        return startUser(userId, /* foreground */ false);
17015    }
17016
17017    /**
17018     * Refreshes the list of users related to the current user when either a
17019     * user switch happens or when a new related user is started in the
17020     * background.
17021     */
17022    private void updateCurrentProfileIdsLocked() {
17023        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17024                mCurrentUserId, false /* enabledOnly */);
17025        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17026        for (int i = 0; i < currentProfileIds.length; i++) {
17027            currentProfileIds[i] = profiles.get(i).id;
17028        }
17029        mCurrentProfileIds = currentProfileIds;
17030
17031        synchronized (mUserProfileGroupIdsSelfLocked) {
17032            mUserProfileGroupIdsSelfLocked.clear();
17033            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17034            for (int i = 0; i < users.size(); i++) {
17035                UserInfo user = users.get(i);
17036                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17037                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17038                }
17039            }
17040        }
17041    }
17042
17043    private Set getProfileIdsLocked(int userId) {
17044        Set userIds = new HashSet<Integer>();
17045        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17046                userId, false /* enabledOnly */);
17047        for (UserInfo user : profiles) {
17048            userIds.add(Integer.valueOf(user.id));
17049        }
17050        return userIds;
17051    }
17052
17053    @Override
17054    public boolean switchUser(final int userId) {
17055        return startUser(userId, /* foregound */ true);
17056    }
17057
17058    private boolean startUser(final int userId, boolean foreground) {
17059        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17060                != PackageManager.PERMISSION_GRANTED) {
17061            String msg = "Permission Denial: switchUser() from pid="
17062                    + Binder.getCallingPid()
17063                    + ", uid=" + Binder.getCallingUid()
17064                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17065            Slog.w(TAG, msg);
17066            throw new SecurityException(msg);
17067        }
17068
17069        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17070
17071        final long ident = Binder.clearCallingIdentity();
17072        try {
17073            synchronized (this) {
17074                final int oldUserId = mCurrentUserId;
17075                if (oldUserId == userId) {
17076                    return true;
17077                }
17078
17079                mStackSupervisor.setLockTaskModeLocked(null, false);
17080
17081                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17082                if (userInfo == null) {
17083                    Slog.w(TAG, "No user info for user #" + userId);
17084                    return false;
17085                }
17086
17087                if (foreground) {
17088                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17089                            R.anim.screen_user_enter);
17090                }
17091
17092                boolean needStart = false;
17093
17094                // If the user we are switching to is not currently started, then
17095                // we need to start it now.
17096                if (mStartedUsers.get(userId) == null) {
17097                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17098                    updateStartedUserArrayLocked();
17099                    needStart = true;
17100                }
17101
17102                final Integer userIdInt = Integer.valueOf(userId);
17103                mUserLru.remove(userIdInt);
17104                mUserLru.add(userIdInt);
17105
17106                if (foreground) {
17107                    mCurrentUserId = userId;
17108                    updateCurrentProfileIdsLocked();
17109                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17110                    // Once the internal notion of the active user has switched, we lock the device
17111                    // with the option to show the user switcher on the keyguard.
17112                    mWindowManager.lockNow(null);
17113                } else {
17114                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17115                    updateCurrentProfileIdsLocked();
17116                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17117                    mUserLru.remove(currentUserIdInt);
17118                    mUserLru.add(currentUserIdInt);
17119                }
17120
17121                final UserStartedState uss = mStartedUsers.get(userId);
17122
17123                // Make sure user is in the started state.  If it is currently
17124                // stopping, we need to knock that off.
17125                if (uss.mState == UserStartedState.STATE_STOPPING) {
17126                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17127                    // so we can just fairly silently bring the user back from
17128                    // the almost-dead.
17129                    uss.mState = UserStartedState.STATE_RUNNING;
17130                    updateStartedUserArrayLocked();
17131                    needStart = true;
17132                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17133                    // This means ACTION_SHUTDOWN has been sent, so we will
17134                    // need to treat this as a new boot of the user.
17135                    uss.mState = UserStartedState.STATE_BOOTING;
17136                    updateStartedUserArrayLocked();
17137                    needStart = true;
17138                }
17139
17140                if (uss.mState == UserStartedState.STATE_BOOTING) {
17141                    // Booting up a new user, need to tell system services about it.
17142                    // Note that this is on the same handler as scheduling of broadcasts,
17143                    // which is important because it needs to go first.
17144                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17145                }
17146
17147                if (foreground) {
17148                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17149                            oldUserId));
17150                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17151                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17152                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17153                            oldUserId, userId, uss));
17154                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17155                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17156                }
17157
17158                if (needStart) {
17159                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17160                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17161                            | Intent.FLAG_RECEIVER_FOREGROUND);
17162                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17163                    broadcastIntentLocked(null, null, intent,
17164                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17165                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17166                }
17167
17168                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17169                    if (userId != UserHandle.USER_OWNER) {
17170                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17171                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17172                        broadcastIntentLocked(null, null, intent, null,
17173                                new IIntentReceiver.Stub() {
17174                                    public void performReceive(Intent intent, int resultCode,
17175                                            String data, Bundle extras, boolean ordered,
17176                                            boolean sticky, int sendingUser) {
17177                                        userInitialized(uss, userId);
17178                                    }
17179                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17180                                true, false, MY_PID, Process.SYSTEM_UID,
17181                                userId);
17182                        uss.initializing = true;
17183                    } else {
17184                        getUserManagerLocked().makeInitialized(userInfo.id);
17185                    }
17186                }
17187
17188                if (foreground) {
17189                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17190                    if (homeInFront) {
17191                        startHomeActivityLocked(userId);
17192                    } else {
17193                        mStackSupervisor.resumeTopActivitiesLocked();
17194                    }
17195                    EventLogTags.writeAmSwitchUser(userId);
17196                    getUserManagerLocked().userForeground(userId);
17197                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17198                } else {
17199                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17200                }
17201
17202                if (needStart) {
17203                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17204                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17205                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17206                    broadcastIntentLocked(null, null, intent,
17207                            null, new IIntentReceiver.Stub() {
17208                                @Override
17209                                public void performReceive(Intent intent, int resultCode, String data,
17210                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17211                                        throws RemoteException {
17212                                }
17213                            }, 0, null, null,
17214                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17215                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17216                }
17217            }
17218        } finally {
17219            Binder.restoreCallingIdentity(ident);
17220        }
17221
17222        return true;
17223    }
17224
17225    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17226        long ident = Binder.clearCallingIdentity();
17227        try {
17228            Intent intent;
17229            if (oldUserId >= 0) {
17230                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17231                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17232                int count = profiles.size();
17233                for (int i = 0; i < count; i++) {
17234                    int profileUserId = profiles.get(i).id;
17235                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17236                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17237                            | Intent.FLAG_RECEIVER_FOREGROUND);
17238                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17239                    broadcastIntentLocked(null, null, intent,
17240                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17241                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17242                }
17243            }
17244            if (newUserId >= 0) {
17245                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17246                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17247                int count = profiles.size();
17248                for (int i = 0; i < count; i++) {
17249                    int profileUserId = profiles.get(i).id;
17250                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17251                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17252                            | Intent.FLAG_RECEIVER_FOREGROUND);
17253                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17254                    broadcastIntentLocked(null, null, intent,
17255                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17256                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17257                }
17258                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17259                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17260                        | Intent.FLAG_RECEIVER_FOREGROUND);
17261                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17262                broadcastIntentLocked(null, null, intent,
17263                        null, null, 0, null, null,
17264                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17265                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17266            }
17267        } finally {
17268            Binder.restoreCallingIdentity(ident);
17269        }
17270    }
17271
17272    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17273            final int newUserId) {
17274        final int N = mUserSwitchObservers.beginBroadcast();
17275        if (N > 0) {
17276            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17277                int mCount = 0;
17278                @Override
17279                public void sendResult(Bundle data) throws RemoteException {
17280                    synchronized (ActivityManagerService.this) {
17281                        if (mCurUserSwitchCallback == this) {
17282                            mCount++;
17283                            if (mCount == N) {
17284                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17285                            }
17286                        }
17287                    }
17288                }
17289            };
17290            synchronized (this) {
17291                uss.switching = true;
17292                mCurUserSwitchCallback = callback;
17293            }
17294            for (int i=0; i<N; i++) {
17295                try {
17296                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17297                            newUserId, callback);
17298                } catch (RemoteException e) {
17299                }
17300            }
17301        } else {
17302            synchronized (this) {
17303                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17304            }
17305        }
17306        mUserSwitchObservers.finishBroadcast();
17307    }
17308
17309    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17310        synchronized (this) {
17311            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17312            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17313        }
17314    }
17315
17316    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17317        mCurUserSwitchCallback = null;
17318        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17319        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17320                oldUserId, newUserId, uss));
17321    }
17322
17323    void userInitialized(UserStartedState uss, int newUserId) {
17324        completeSwitchAndInitalize(uss, newUserId, true, false);
17325    }
17326
17327    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17328        completeSwitchAndInitalize(uss, newUserId, false, true);
17329    }
17330
17331    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17332            boolean clearInitializing, boolean clearSwitching) {
17333        boolean unfrozen = false;
17334        synchronized (this) {
17335            if (clearInitializing) {
17336                uss.initializing = false;
17337                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17338            }
17339            if (clearSwitching) {
17340                uss.switching = false;
17341            }
17342            if (!uss.switching && !uss.initializing) {
17343                mWindowManager.stopFreezingScreen();
17344                unfrozen = true;
17345            }
17346        }
17347        if (unfrozen) {
17348            final int N = mUserSwitchObservers.beginBroadcast();
17349            for (int i=0; i<N; i++) {
17350                try {
17351                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17352                } catch (RemoteException e) {
17353                }
17354            }
17355            mUserSwitchObservers.finishBroadcast();
17356        }
17357    }
17358
17359    void scheduleStartProfilesLocked() {
17360        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17361            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17362                    DateUtils.SECOND_IN_MILLIS);
17363        }
17364    }
17365
17366    void startProfilesLocked() {
17367        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17368        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17369                mCurrentUserId, false /* enabledOnly */);
17370        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17371        for (UserInfo user : profiles) {
17372            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17373                    && user.id != mCurrentUserId) {
17374                toStart.add(user);
17375            }
17376        }
17377        final int n = toStart.size();
17378        int i = 0;
17379        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17380            startUserInBackground(toStart.get(i).id);
17381        }
17382        if (i < n) {
17383            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17384        }
17385    }
17386
17387    void finishUserBoot(UserStartedState uss) {
17388        synchronized (this) {
17389            if (uss.mState == UserStartedState.STATE_BOOTING
17390                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17391                uss.mState = UserStartedState.STATE_RUNNING;
17392                final int userId = uss.mHandle.getIdentifier();
17393                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17394                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17395                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17396                broadcastIntentLocked(null, null, intent,
17397                        null, null, 0, null, null,
17398                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17399                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17400            }
17401        }
17402    }
17403
17404    void finishUserSwitch(UserStartedState uss) {
17405        synchronized (this) {
17406            finishUserBoot(uss);
17407
17408            startProfilesLocked();
17409
17410            int num = mUserLru.size();
17411            int i = 0;
17412            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17413                Integer oldUserId = mUserLru.get(i);
17414                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17415                if (oldUss == null) {
17416                    // Shouldn't happen, but be sane if it does.
17417                    mUserLru.remove(i);
17418                    num--;
17419                    continue;
17420                }
17421                if (oldUss.mState == UserStartedState.STATE_STOPPING
17422                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17423                    // This user is already stopping, doesn't count.
17424                    num--;
17425                    i++;
17426                    continue;
17427                }
17428                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17429                    // Owner and current can't be stopped, but count as running.
17430                    i++;
17431                    continue;
17432                }
17433                // This is a user to be stopped.
17434                stopUserLocked(oldUserId, null);
17435                num--;
17436                i++;
17437            }
17438        }
17439    }
17440
17441    @Override
17442    public int stopUser(final int userId, final IStopUserCallback callback) {
17443        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17444                != PackageManager.PERMISSION_GRANTED) {
17445            String msg = "Permission Denial: switchUser() from pid="
17446                    + Binder.getCallingPid()
17447                    + ", uid=" + Binder.getCallingUid()
17448                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17449            Slog.w(TAG, msg);
17450            throw new SecurityException(msg);
17451        }
17452        if (userId <= 0) {
17453            throw new IllegalArgumentException("Can't stop primary user " + userId);
17454        }
17455        synchronized (this) {
17456            return stopUserLocked(userId, callback);
17457        }
17458    }
17459
17460    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17461        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17462        if (mCurrentUserId == userId) {
17463            return ActivityManager.USER_OP_IS_CURRENT;
17464        }
17465
17466        final UserStartedState uss = mStartedUsers.get(userId);
17467        if (uss == null) {
17468            // User is not started, nothing to do...  but we do need to
17469            // callback if requested.
17470            if (callback != null) {
17471                mHandler.post(new Runnable() {
17472                    @Override
17473                    public void run() {
17474                        try {
17475                            callback.userStopped(userId);
17476                        } catch (RemoteException e) {
17477                        }
17478                    }
17479                });
17480            }
17481            return ActivityManager.USER_OP_SUCCESS;
17482        }
17483
17484        if (callback != null) {
17485            uss.mStopCallbacks.add(callback);
17486        }
17487
17488        if (uss.mState != UserStartedState.STATE_STOPPING
17489                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17490            uss.mState = UserStartedState.STATE_STOPPING;
17491            updateStartedUserArrayLocked();
17492
17493            long ident = Binder.clearCallingIdentity();
17494            try {
17495                // We are going to broadcast ACTION_USER_STOPPING and then
17496                // once that is done send a final ACTION_SHUTDOWN and then
17497                // stop the user.
17498                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17499                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17500                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17501                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17502                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17503                // This is the result receiver for the final shutdown broadcast.
17504                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17505                    @Override
17506                    public void performReceive(Intent intent, int resultCode, String data,
17507                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17508                        finishUserStop(uss);
17509                    }
17510                };
17511                // This is the result receiver for the initial stopping broadcast.
17512                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17513                    @Override
17514                    public void performReceive(Intent intent, int resultCode, String data,
17515                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17516                        // On to the next.
17517                        synchronized (ActivityManagerService.this) {
17518                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17519                                // Whoops, we are being started back up.  Abort, abort!
17520                                return;
17521                            }
17522                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17523                        }
17524                        mBatteryStatsService.noteEvent(
17525                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17526                                Integer.toString(userId), userId);
17527                        mSystemServiceManager.stopUser(userId);
17528                        broadcastIntentLocked(null, null, shutdownIntent,
17529                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17530                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17531                    }
17532                };
17533                // Kick things off.
17534                broadcastIntentLocked(null, null, stoppingIntent,
17535                        null, stoppingReceiver, 0, null, null,
17536                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17537                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17538            } finally {
17539                Binder.restoreCallingIdentity(ident);
17540            }
17541        }
17542
17543        return ActivityManager.USER_OP_SUCCESS;
17544    }
17545
17546    void finishUserStop(UserStartedState uss) {
17547        final int userId = uss.mHandle.getIdentifier();
17548        boolean stopped;
17549        ArrayList<IStopUserCallback> callbacks;
17550        synchronized (this) {
17551            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17552            if (mStartedUsers.get(userId) != uss) {
17553                stopped = false;
17554            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17555                stopped = false;
17556            } else {
17557                stopped = true;
17558                // User can no longer run.
17559                mStartedUsers.remove(userId);
17560                mUserLru.remove(Integer.valueOf(userId));
17561                updateStartedUserArrayLocked();
17562
17563                // Clean up all state and processes associated with the user.
17564                // Kill all the processes for the user.
17565                forceStopUserLocked(userId, "finish user");
17566            }
17567        }
17568
17569        for (int i=0; i<callbacks.size(); i++) {
17570            try {
17571                if (stopped) callbacks.get(i).userStopped(userId);
17572                else callbacks.get(i).userStopAborted(userId);
17573            } catch (RemoteException e) {
17574            }
17575        }
17576
17577        if (stopped) {
17578            mSystemServiceManager.cleanupUser(userId);
17579            synchronized (this) {
17580                mStackSupervisor.removeUserLocked(userId);
17581            }
17582        }
17583    }
17584
17585    @Override
17586    public UserInfo getCurrentUser() {
17587        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17588                != PackageManager.PERMISSION_GRANTED) && (
17589                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17590                != PackageManager.PERMISSION_GRANTED)) {
17591            String msg = "Permission Denial: getCurrentUser() from pid="
17592                    + Binder.getCallingPid()
17593                    + ", uid=" + Binder.getCallingUid()
17594                    + " requires " + INTERACT_ACROSS_USERS;
17595            Slog.w(TAG, msg);
17596            throw new SecurityException(msg);
17597        }
17598        synchronized (this) {
17599            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17600        }
17601    }
17602
17603    int getCurrentUserIdLocked() {
17604        return mCurrentUserId;
17605    }
17606
17607    @Override
17608    public boolean isUserRunning(int userId, boolean orStopped) {
17609        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17610                != PackageManager.PERMISSION_GRANTED) {
17611            String msg = "Permission Denial: isUserRunning() from pid="
17612                    + Binder.getCallingPid()
17613                    + ", uid=" + Binder.getCallingUid()
17614                    + " requires " + INTERACT_ACROSS_USERS;
17615            Slog.w(TAG, msg);
17616            throw new SecurityException(msg);
17617        }
17618        synchronized (this) {
17619            return isUserRunningLocked(userId, orStopped);
17620        }
17621    }
17622
17623    boolean isUserRunningLocked(int userId, boolean orStopped) {
17624        UserStartedState state = mStartedUsers.get(userId);
17625        if (state == null) {
17626            return false;
17627        }
17628        if (orStopped) {
17629            return true;
17630        }
17631        return state.mState != UserStartedState.STATE_STOPPING
17632                && state.mState != UserStartedState.STATE_SHUTDOWN;
17633    }
17634
17635    @Override
17636    public int[] getRunningUserIds() {
17637        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17638                != PackageManager.PERMISSION_GRANTED) {
17639            String msg = "Permission Denial: isUserRunning() from pid="
17640                    + Binder.getCallingPid()
17641                    + ", uid=" + Binder.getCallingUid()
17642                    + " requires " + INTERACT_ACROSS_USERS;
17643            Slog.w(TAG, msg);
17644            throw new SecurityException(msg);
17645        }
17646        synchronized (this) {
17647            return mStartedUserArray;
17648        }
17649    }
17650
17651    private void updateStartedUserArrayLocked() {
17652        int num = 0;
17653        for (int i=0; i<mStartedUsers.size();  i++) {
17654            UserStartedState uss = mStartedUsers.valueAt(i);
17655            // This list does not include stopping users.
17656            if (uss.mState != UserStartedState.STATE_STOPPING
17657                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17658                num++;
17659            }
17660        }
17661        mStartedUserArray = new int[num];
17662        num = 0;
17663        for (int i=0; i<mStartedUsers.size();  i++) {
17664            UserStartedState uss = mStartedUsers.valueAt(i);
17665            if (uss.mState != UserStartedState.STATE_STOPPING
17666                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17667                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17668                num++;
17669            }
17670        }
17671    }
17672
17673    @Override
17674    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17675        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17676                != PackageManager.PERMISSION_GRANTED) {
17677            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17678                    + Binder.getCallingPid()
17679                    + ", uid=" + Binder.getCallingUid()
17680                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17681            Slog.w(TAG, msg);
17682            throw new SecurityException(msg);
17683        }
17684
17685        mUserSwitchObservers.register(observer);
17686    }
17687
17688    @Override
17689    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17690        mUserSwitchObservers.unregister(observer);
17691    }
17692
17693    private boolean userExists(int userId) {
17694        if (userId == 0) {
17695            return true;
17696        }
17697        UserManagerService ums = getUserManagerLocked();
17698        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17699    }
17700
17701    int[] getUsersLocked() {
17702        UserManagerService ums = getUserManagerLocked();
17703        return ums != null ? ums.getUserIds() : new int[] { 0 };
17704    }
17705
17706    UserManagerService getUserManagerLocked() {
17707        if (mUserManager == null) {
17708            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17709            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17710        }
17711        return mUserManager;
17712    }
17713
17714    private int applyUserId(int uid, int userId) {
17715        return UserHandle.getUid(userId, uid);
17716    }
17717
17718    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17719        if (info == null) return null;
17720        ApplicationInfo newInfo = new ApplicationInfo(info);
17721        newInfo.uid = applyUserId(info.uid, userId);
17722        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17723                + info.packageName;
17724        return newInfo;
17725    }
17726
17727    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17728        if (aInfo == null
17729                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17730            return aInfo;
17731        }
17732
17733        ActivityInfo info = new ActivityInfo(aInfo);
17734        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17735        return info;
17736    }
17737
17738    private final class LocalService extends ActivityManagerInternal {
17739        @Override
17740        public void goingToSleep() {
17741            ActivityManagerService.this.goingToSleep();
17742        }
17743
17744        @Override
17745        public void wakingUp() {
17746            ActivityManagerService.this.wakingUp();
17747        }
17748    }
17749
17750    /**
17751     * An implementation of IAppTask, that allows an app to manage its own tasks via
17752     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17753     * only the process that calls getAppTasks() can call the AppTask methods.
17754     */
17755    class AppTaskImpl extends IAppTask.Stub {
17756        private int mTaskId;
17757        private int mCallingUid;
17758
17759        public AppTaskImpl(int taskId, int callingUid) {
17760            mTaskId = taskId;
17761            mCallingUid = callingUid;
17762        }
17763
17764        @Override
17765        public void finishAndRemoveTask() {
17766            // Ensure that we are called from the same process that created this AppTask
17767            if (mCallingUid != Binder.getCallingUid()) {
17768                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17769                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17770                return;
17771            }
17772
17773            synchronized (ActivityManagerService.this) {
17774                long origId = Binder.clearCallingIdentity();
17775                try {
17776                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17777                    if (tr != null) {
17778                        // Only kill the process if we are not a new document
17779                        int flags = tr.getBaseIntent().getFlags();
17780                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17781                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17782                        removeTaskByIdLocked(mTaskId,
17783                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17784                    }
17785                } finally {
17786                    Binder.restoreCallingIdentity(origId);
17787                }
17788            }
17789        }
17790
17791        @Override
17792        public ActivityManager.RecentTaskInfo getTaskInfo() {
17793            // Ensure that we are called from the same process that created this AppTask
17794            if (mCallingUid != Binder.getCallingUid()) {
17795                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17796                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17797                return null;
17798            }
17799
17800            synchronized (ActivityManagerService.this) {
17801                long origId = Binder.clearCallingIdentity();
17802                try {
17803                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17804                    if (tr != null) {
17805                        return createRecentTaskInfoFromTaskRecord(tr);
17806                    }
17807                } finally {
17808                    Binder.restoreCallingIdentity(origId);
17809                }
17810                return null;
17811            }
17812        }
17813    }
17814}
17815