ActivityManagerService.java revision 0b633fc12188ac9a78c0cea9cacc8e90d08260dc
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) {
6567        if (targetPkg == null) {
6568            throw new NullPointerException("targetPkg");
6569        }
6570
6571        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6572                -1);
6573        if (targetUid < 0) {
6574            return;
6575        }
6576
6577        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6578                owner);
6579    }
6580
6581    static class NeededUriGrants extends ArrayList<GrantUri> {
6582        final String targetPkg;
6583        final int targetUid;
6584        final int flags;
6585
6586        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6587            this.targetPkg = targetPkg;
6588            this.targetUid = targetUid;
6589            this.flags = flags;
6590        }
6591    }
6592
6593    /**
6594     * Like checkGrantUriPermissionLocked, but takes an Intent.
6595     */
6596    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6597            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6598        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6599                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6600                + " clip=" + (intent != null ? intent.getClipData() : null)
6601                + " from " + intent + "; flags=0x"
6602                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6603
6604        if (targetPkg == null) {
6605            throw new NullPointerException("targetPkg");
6606        }
6607
6608        if (intent == null) {
6609            return null;
6610        }
6611        Uri data = intent.getData();
6612        ClipData clip = intent.getClipData();
6613        if (data == null && clip == null) {
6614            return null;
6615        }
6616        final IPackageManager pm = AppGlobals.getPackageManager();
6617        int targetUid;
6618        if (needed != null) {
6619            targetUid = needed.targetUid;
6620        } else {
6621            try {
6622                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6623            } catch (RemoteException ex) {
6624                return null;
6625            }
6626            if (targetUid < 0) {
6627                if (DEBUG_URI_PERMISSION) {
6628                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6629                            + " on user " + targetUserId);
6630                }
6631                return null;
6632            }
6633        }
6634        if (data != null) {
6635            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6636            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6637                    targetUid);
6638            if (targetUid > 0) {
6639                if (needed == null) {
6640                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6641                }
6642                needed.add(grantUri);
6643            }
6644        }
6645        if (clip != null) {
6646            for (int i=0; i<clip.getItemCount(); i++) {
6647                Uri uri = clip.getItemAt(i).getUri();
6648                if (uri != null) {
6649                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6650                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6651                            targetUid);
6652                    if (targetUid > 0) {
6653                        if (needed == null) {
6654                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6655                        }
6656                        needed.add(grantUri);
6657                    }
6658                } else {
6659                    Intent clipIntent = clip.getItemAt(i).getIntent();
6660                    if (clipIntent != null) {
6661                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6662                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6663                        if (newNeeded != null) {
6664                            needed = newNeeded;
6665                        }
6666                    }
6667                }
6668            }
6669        }
6670
6671        return needed;
6672    }
6673
6674    /**
6675     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6676     */
6677    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6678            UriPermissionOwner owner) {
6679        if (needed != null) {
6680            for (int i=0; i<needed.size(); i++) {
6681                GrantUri grantUri = needed.get(i);
6682                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6683                        grantUri, needed.flags, owner);
6684            }
6685        }
6686    }
6687
6688    void grantUriPermissionFromIntentLocked(int callingUid,
6689            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6690        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6691                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6692        if (needed == null) {
6693            return;
6694        }
6695
6696        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6697    }
6698
6699    @Override
6700    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6701            final int modeFlags, int userId) {
6702        enforceNotIsolatedCaller("grantUriPermission");
6703        GrantUri grantUri = new GrantUri(userId, uri, false);
6704        synchronized(this) {
6705            final ProcessRecord r = getRecordForAppLocked(caller);
6706            if (r == null) {
6707                throw new SecurityException("Unable to find app for caller "
6708                        + caller
6709                        + " when granting permission to uri " + grantUri);
6710            }
6711            if (targetPkg == null) {
6712                throw new IllegalArgumentException("null target");
6713            }
6714            if (grantUri == null) {
6715                throw new IllegalArgumentException("null uri");
6716            }
6717
6718            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6719                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6720                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6721                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6722
6723            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6724        }
6725    }
6726
6727    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6728        if (perm.modeFlags == 0) {
6729            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6730                    perm.targetUid);
6731            if (perms != null) {
6732                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6733                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6734
6735                perms.remove(perm.uri);
6736                if (perms.isEmpty()) {
6737                    mGrantedUriPermissions.remove(perm.targetUid);
6738                }
6739            }
6740        }
6741    }
6742
6743    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6744        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6745
6746        final IPackageManager pm = AppGlobals.getPackageManager();
6747        final String authority = grantUri.uri.getAuthority();
6748        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6749        if (pi == null) {
6750            Slog.w(TAG, "No content provider found for permission revoke: "
6751                    + grantUri.toSafeString());
6752            return;
6753        }
6754
6755        // Does the caller have this permission on the URI?
6756        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6757            // Right now, if you are not the original owner of the permission,
6758            // you are not allowed to revoke it.
6759            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6760                throw new SecurityException("Uid " + callingUid
6761                        + " does not have permission to uri " + grantUri);
6762            //}
6763        }
6764
6765        boolean persistChanged = false;
6766
6767        // Go through all of the permissions and remove any that match.
6768        int N = mGrantedUriPermissions.size();
6769        for (int i = 0; i < N; i++) {
6770            final int targetUid = mGrantedUriPermissions.keyAt(i);
6771            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6772
6773            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6774                final UriPermission perm = it.next();
6775                if (perm.uri.sourceUserId == grantUri.sourceUserId
6776                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6777                    if (DEBUG_URI_PERMISSION)
6778                        Slog.v(TAG,
6779                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6780                    persistChanged |= perm.revokeModes(
6781                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6782                    if (perm.modeFlags == 0) {
6783                        it.remove();
6784                    }
6785                }
6786            }
6787
6788            if (perms.isEmpty()) {
6789                mGrantedUriPermissions.remove(targetUid);
6790                N--;
6791                i--;
6792            }
6793        }
6794
6795        if (persistChanged) {
6796            schedulePersistUriGrants();
6797        }
6798    }
6799
6800    @Override
6801    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6802            int userId) {
6803        enforceNotIsolatedCaller("revokeUriPermission");
6804        synchronized(this) {
6805            final ProcessRecord r = getRecordForAppLocked(caller);
6806            if (r == null) {
6807                throw new SecurityException("Unable to find app for caller "
6808                        + caller
6809                        + " when revoking permission to uri " + uri);
6810            }
6811            if (uri == null) {
6812                Slog.w(TAG, "revokeUriPermission: null uri");
6813                return;
6814            }
6815
6816            if (!Intent.isAccessUriMode(modeFlags)) {
6817                return;
6818            }
6819
6820            final IPackageManager pm = AppGlobals.getPackageManager();
6821            final String authority = uri.getAuthority();
6822            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6823            if (pi == null) {
6824                Slog.w(TAG, "No content provider found for permission revoke: "
6825                        + uri.toSafeString());
6826                return;
6827            }
6828
6829            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6830        }
6831    }
6832
6833    /**
6834     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6835     * given package.
6836     *
6837     * @param packageName Package name to match, or {@code null} to apply to all
6838     *            packages.
6839     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6840     *            to all users.
6841     * @param persistable If persistable grants should be removed.
6842     */
6843    private void removeUriPermissionsForPackageLocked(
6844            String packageName, int userHandle, boolean persistable) {
6845        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6846            throw new IllegalArgumentException("Must narrow by either package or user");
6847        }
6848
6849        boolean persistChanged = false;
6850
6851        int N = mGrantedUriPermissions.size();
6852        for (int i = 0; i < N; i++) {
6853            final int targetUid = mGrantedUriPermissions.keyAt(i);
6854            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6855
6856            // Only inspect grants matching user
6857            if (userHandle == UserHandle.USER_ALL
6858                    || userHandle == UserHandle.getUserId(targetUid)) {
6859                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6860                    final UriPermission perm = it.next();
6861
6862                    // Only inspect grants matching package
6863                    if (packageName == null || perm.sourcePkg.equals(packageName)
6864                            || perm.targetPkg.equals(packageName)) {
6865                        persistChanged |= perm.revokeModes(
6866                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6867
6868                        // Only remove when no modes remain; any persisted grants
6869                        // will keep this alive.
6870                        if (perm.modeFlags == 0) {
6871                            it.remove();
6872                        }
6873                    }
6874                }
6875
6876                if (perms.isEmpty()) {
6877                    mGrantedUriPermissions.remove(targetUid);
6878                    N--;
6879                    i--;
6880                }
6881            }
6882        }
6883
6884        if (persistChanged) {
6885            schedulePersistUriGrants();
6886        }
6887    }
6888
6889    @Override
6890    public IBinder newUriPermissionOwner(String name) {
6891        enforceNotIsolatedCaller("newUriPermissionOwner");
6892        synchronized(this) {
6893            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6894            return owner.getExternalTokenLocked();
6895        }
6896    }
6897
6898    @Override
6899    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6900            final int modeFlags, int userId) {
6901        synchronized(this) {
6902            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6903            if (owner == null) {
6904                throw new IllegalArgumentException("Unknown owner: " + token);
6905            }
6906            if (fromUid != Binder.getCallingUid()) {
6907                if (Binder.getCallingUid() != Process.myUid()) {
6908                    // Only system code can grant URI permissions on behalf
6909                    // of other users.
6910                    throw new SecurityException("nice try");
6911                }
6912            }
6913            if (targetPkg == null) {
6914                throw new IllegalArgumentException("null target");
6915            }
6916            if (uri == null) {
6917                throw new IllegalArgumentException("null uri");
6918            }
6919
6920            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6921                    modeFlags, owner);
6922        }
6923    }
6924
6925    @Override
6926    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6927        synchronized(this) {
6928            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6929            if (owner == null) {
6930                throw new IllegalArgumentException("Unknown owner: " + token);
6931            }
6932
6933            if (uri == null) {
6934                owner.removeUriPermissionsLocked(mode);
6935            } else {
6936                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6937            }
6938        }
6939    }
6940
6941    private void schedulePersistUriGrants() {
6942        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6943            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6944                    10 * DateUtils.SECOND_IN_MILLIS);
6945        }
6946    }
6947
6948    private void writeGrantedUriPermissions() {
6949        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6950
6951        // Snapshot permissions so we can persist without lock
6952        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6953        synchronized (this) {
6954            final int size = mGrantedUriPermissions.size();
6955            for (int i = 0; i < size; i++) {
6956                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6957                for (UriPermission perm : perms.values()) {
6958                    if (perm.persistedModeFlags != 0) {
6959                        persist.add(perm.snapshot());
6960                    }
6961                }
6962            }
6963        }
6964
6965        FileOutputStream fos = null;
6966        try {
6967            fos = mGrantFile.startWrite();
6968
6969            XmlSerializer out = new FastXmlSerializer();
6970            out.setOutput(fos, "utf-8");
6971            out.startDocument(null, true);
6972            out.startTag(null, TAG_URI_GRANTS);
6973            for (UriPermission.Snapshot perm : persist) {
6974                out.startTag(null, TAG_URI_GRANT);
6975                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6976                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6977                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6978                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6979                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6980                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6981                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6982                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6983                out.endTag(null, TAG_URI_GRANT);
6984            }
6985            out.endTag(null, TAG_URI_GRANTS);
6986            out.endDocument();
6987
6988            mGrantFile.finishWrite(fos);
6989        } catch (IOException e) {
6990            if (fos != null) {
6991                mGrantFile.failWrite(fos);
6992            }
6993        }
6994    }
6995
6996    private void readGrantedUriPermissionsLocked() {
6997        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6998
6999        final long now = System.currentTimeMillis();
7000
7001        FileInputStream fis = null;
7002        try {
7003            fis = mGrantFile.openRead();
7004            final XmlPullParser in = Xml.newPullParser();
7005            in.setInput(fis, null);
7006
7007            int type;
7008            while ((type = in.next()) != END_DOCUMENT) {
7009                final String tag = in.getName();
7010                if (type == START_TAG) {
7011                    if (TAG_URI_GRANT.equals(tag)) {
7012                        final int sourceUserId;
7013                        final int targetUserId;
7014                        final int userHandle = readIntAttribute(in,
7015                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7016                        if (userHandle != UserHandle.USER_NULL) {
7017                            // For backwards compatibility.
7018                            sourceUserId = userHandle;
7019                            targetUserId = userHandle;
7020                        } else {
7021                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7022                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7023                        }
7024                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7025                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7026                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7027                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7028                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7029                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7030
7031                        // Sanity check that provider still belongs to source package
7032                        final ProviderInfo pi = getProviderInfoLocked(
7033                                uri.getAuthority(), sourceUserId);
7034                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7035                            int targetUid = -1;
7036                            try {
7037                                targetUid = AppGlobals.getPackageManager()
7038                                        .getPackageUid(targetPkg, targetUserId);
7039                            } catch (RemoteException e) {
7040                            }
7041                            if (targetUid != -1) {
7042                                final UriPermission perm = findOrCreateUriPermissionLocked(
7043                                        sourcePkg, targetPkg, targetUid,
7044                                        new GrantUri(sourceUserId, uri, prefix));
7045                                perm.initPersistedModes(modeFlags, createdTime);
7046                            }
7047                        } else {
7048                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7049                                    + " but instead found " + pi);
7050                        }
7051                    }
7052                }
7053            }
7054        } catch (FileNotFoundException e) {
7055            // Missing grants is okay
7056        } catch (IOException e) {
7057            Log.wtf(TAG, "Failed reading Uri grants", e);
7058        } catch (XmlPullParserException e) {
7059            Log.wtf(TAG, "Failed reading Uri grants", e);
7060        } finally {
7061            IoUtils.closeQuietly(fis);
7062        }
7063    }
7064
7065    @Override
7066    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7067        enforceNotIsolatedCaller("takePersistableUriPermission");
7068
7069        Preconditions.checkFlagsArgument(modeFlags,
7070                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7071
7072        synchronized (this) {
7073            final int callingUid = Binder.getCallingUid();
7074            boolean persistChanged = false;
7075            GrantUri grantUri = new GrantUri(userId, uri, false);
7076
7077            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7078                    new GrantUri(userId, uri, false));
7079            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7080                    new GrantUri(userId, uri, true));
7081
7082            final boolean exactValid = (exactPerm != null)
7083                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7084            final boolean prefixValid = (prefixPerm != null)
7085                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7086
7087            if (!(exactValid || prefixValid)) {
7088                throw new SecurityException("No persistable permission grants found for UID "
7089                        + callingUid + " and Uri " + grantUri.toSafeString());
7090            }
7091
7092            if (exactValid) {
7093                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7094            }
7095            if (prefixValid) {
7096                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7097            }
7098
7099            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7100
7101            if (persistChanged) {
7102                schedulePersistUriGrants();
7103            }
7104        }
7105    }
7106
7107    @Override
7108    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7109        enforceNotIsolatedCaller("releasePersistableUriPermission");
7110
7111        Preconditions.checkFlagsArgument(modeFlags,
7112                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7113
7114        synchronized (this) {
7115            final int callingUid = Binder.getCallingUid();
7116            boolean persistChanged = false;
7117
7118            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7119                    new GrantUri(userId, uri, false));
7120            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7121                    new GrantUri(userId, uri, true));
7122            if (exactPerm == null && prefixPerm == null) {
7123                throw new SecurityException("No permission grants found for UID " + callingUid
7124                        + " and Uri " + uri.toSafeString());
7125            }
7126
7127            if (exactPerm != null) {
7128                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7129                removeUriPermissionIfNeededLocked(exactPerm);
7130            }
7131            if (prefixPerm != null) {
7132                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7133                removeUriPermissionIfNeededLocked(prefixPerm);
7134            }
7135
7136            if (persistChanged) {
7137                schedulePersistUriGrants();
7138            }
7139        }
7140    }
7141
7142    /**
7143     * Prune any older {@link UriPermission} for the given UID until outstanding
7144     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7145     *
7146     * @return if any mutations occured that require persisting.
7147     */
7148    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7149        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7150        if (perms == null) return false;
7151        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7152
7153        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7154        for (UriPermission perm : perms.values()) {
7155            if (perm.persistedModeFlags != 0) {
7156                persisted.add(perm);
7157            }
7158        }
7159
7160        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7161        if (trimCount <= 0) return false;
7162
7163        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7164        for (int i = 0; i < trimCount; i++) {
7165            final UriPermission perm = persisted.get(i);
7166
7167            if (DEBUG_URI_PERMISSION) {
7168                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7169            }
7170
7171            perm.releasePersistableModes(~0);
7172            removeUriPermissionIfNeededLocked(perm);
7173        }
7174
7175        return true;
7176    }
7177
7178    @Override
7179    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7180            String packageName, boolean incoming) {
7181        enforceNotIsolatedCaller("getPersistedUriPermissions");
7182        Preconditions.checkNotNull(packageName, "packageName");
7183
7184        final int callingUid = Binder.getCallingUid();
7185        final IPackageManager pm = AppGlobals.getPackageManager();
7186        try {
7187            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7188            if (packageUid != callingUid) {
7189                throw new SecurityException(
7190                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7191            }
7192        } catch (RemoteException e) {
7193            throw new SecurityException("Failed to verify package name ownership");
7194        }
7195
7196        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7197        synchronized (this) {
7198            if (incoming) {
7199                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7200                        callingUid);
7201                if (perms == null) {
7202                    Slog.w(TAG, "No permission grants found for " + packageName);
7203                } else {
7204                    for (UriPermission perm : perms.values()) {
7205                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7206                            result.add(perm.buildPersistedPublicApiObject());
7207                        }
7208                    }
7209                }
7210            } else {
7211                final int size = mGrantedUriPermissions.size();
7212                for (int i = 0; i < size; i++) {
7213                    final ArrayMap<GrantUri, UriPermission> perms =
7214                            mGrantedUriPermissions.valueAt(i);
7215                    for (UriPermission perm : perms.values()) {
7216                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7217                            result.add(perm.buildPersistedPublicApiObject());
7218                        }
7219                    }
7220                }
7221            }
7222        }
7223        return new ParceledListSlice<android.content.UriPermission>(result);
7224    }
7225
7226    @Override
7227    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7228        synchronized (this) {
7229            ProcessRecord app =
7230                who != null ? getRecordForAppLocked(who) : null;
7231            if (app == null) return;
7232
7233            Message msg = Message.obtain();
7234            msg.what = WAIT_FOR_DEBUGGER_MSG;
7235            msg.obj = app;
7236            msg.arg1 = waiting ? 1 : 0;
7237            mHandler.sendMessage(msg);
7238        }
7239    }
7240
7241    @Override
7242    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7243        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7244        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7245        outInfo.availMem = Process.getFreeMemory();
7246        outInfo.totalMem = Process.getTotalMemory();
7247        outInfo.threshold = homeAppMem;
7248        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7249        outInfo.hiddenAppThreshold = cachedAppMem;
7250        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7251                ProcessList.SERVICE_ADJ);
7252        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7253                ProcessList.VISIBLE_APP_ADJ);
7254        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7255                ProcessList.FOREGROUND_APP_ADJ);
7256    }
7257
7258    // =========================================================
7259    // TASK MANAGEMENT
7260    // =========================================================
7261
7262    @Override
7263    public List<IAppTask> getAppTasks() {
7264        final PackageManager pm = mContext.getPackageManager();
7265        int callingUid = Binder.getCallingUid();
7266        long ident = Binder.clearCallingIdentity();
7267
7268        // Compose the list of packages for this id to test against
7269        HashSet<String> packages = new HashSet<String>();
7270        String[] uidPackages = pm.getPackagesForUid(callingUid);
7271        for (int i = 0; i < uidPackages.length; i++) {
7272            packages.add(uidPackages[i]);
7273        }
7274
7275        synchronized(this) {
7276            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7277            try {
7278                if (localLOGV) Slog.v(TAG, "getAppTasks");
7279
7280                final int N = mRecentTasks.size();
7281                for (int i = 0; i < N; i++) {
7282                    TaskRecord tr = mRecentTasks.get(i);
7283                    // Skip tasks that are not created by the caller
7284                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7285                        ActivityManager.RecentTaskInfo taskInfo =
7286                                createRecentTaskInfoFromTaskRecord(tr);
7287                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7288                        list.add(taskImpl);
7289                    }
7290                }
7291            } finally {
7292                Binder.restoreCallingIdentity(ident);
7293            }
7294            return list;
7295        }
7296    }
7297
7298    @Override
7299    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7300        final int callingUid = Binder.getCallingUid();
7301        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7302
7303        synchronized(this) {
7304            if (localLOGV) Slog.v(
7305                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7306
7307            final boolean allowed = checkCallingPermission(
7308                    android.Manifest.permission.GET_TASKS)
7309                    == PackageManager.PERMISSION_GRANTED;
7310            if (!allowed) {
7311                Slog.w(TAG, "getTasks: caller " + callingUid
7312                        + " does not hold GET_TASKS; limiting output");
7313            }
7314
7315            // TODO: Improve with MRU list from all ActivityStacks.
7316            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7317        }
7318
7319        return list;
7320    }
7321
7322    TaskRecord getMostRecentTask() {
7323        return mRecentTasks.get(0);
7324    }
7325
7326    /**
7327     * Creates a new RecentTaskInfo from a TaskRecord.
7328     */
7329    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7330        // Update the task description to reflect any changes in the task stack
7331        tr.updateTaskDescription();
7332
7333        // Compose the recent task info
7334        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7335        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7336        rti.persistentId = tr.taskId;
7337        rti.baseIntent = new Intent(tr.getBaseIntent());
7338        rti.origActivity = tr.origActivity;
7339        rti.description = tr.lastDescription;
7340        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7341        rti.userId = tr.userId;
7342        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7343        rti.firstActiveTime = tr.firstActiveTime;
7344        rti.lastActiveTime = tr.lastActiveTime;
7345        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7346        return rti;
7347    }
7348
7349    @Override
7350    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7351        final int callingUid = Binder.getCallingUid();
7352        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7353                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7354
7355        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7356        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7357        synchronized (this) {
7358            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7359                    == PackageManager.PERMISSION_GRANTED;
7360            if (!allowed) {
7361                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7362                        + " does not hold GET_TASKS; limiting output");
7363            }
7364            final boolean detailed = checkCallingPermission(
7365                    android.Manifest.permission.GET_DETAILED_TASKS)
7366                    == PackageManager.PERMISSION_GRANTED;
7367
7368            IPackageManager pm = AppGlobals.getPackageManager();
7369
7370            final int N = mRecentTasks.size();
7371            ArrayList<ActivityManager.RecentTaskInfo> res
7372                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7373                            maxNum < N ? maxNum : N);
7374
7375            final Set<Integer> includedUsers;
7376            if (includeProfiles) {
7377                includedUsers = getProfileIdsLocked(userId);
7378            } else {
7379                includedUsers = new HashSet<Integer>();
7380            }
7381            includedUsers.add(Integer.valueOf(userId));
7382
7383            // Regroup affiliated tasks together.
7384            for (int i = 0; i < N; ) {
7385                TaskRecord task = mRecentTasks.remove(i);
7386                if (mTmpRecents.contains(task)) {
7387                    continue;
7388                }
7389                int affiliatedTaskId = task.mAffiliatedTaskId;
7390                while (true) {
7391                    TaskRecord next = task.mNextAffiliate;
7392                    if (next == null) {
7393                        break;
7394                    }
7395                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7396                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7397                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7398                        task.setNextAffiliate(null);
7399                        if (next.mPrevAffiliate == task) {
7400                            next.setPrevAffiliate(null);
7401                        }
7402                        break;
7403                    }
7404                    if (next.mPrevAffiliate != task) {
7405                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7406                                next.mPrevAffiliate + " task=" + task);
7407                        next.setPrevAffiliate(null);
7408                        break;
7409                    }
7410                    if (!mRecentTasks.contains(next)) {
7411                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7412                        task.setNextAffiliate(null);
7413                        if (next.mPrevAffiliate == task) {
7414                            next.setPrevAffiliate(null);
7415                        }
7416                        break;
7417                    }
7418                    task = next;
7419                }
7420                // task is now the end of the list
7421                do {
7422                    mRecentTasks.remove(task);
7423                    mRecentTasks.add(i++, task);
7424                    mTmpRecents.add(task);
7425                } while ((task = task.mPrevAffiliate) != null);
7426            }
7427            mTmpRecents.clear();
7428            // mRecentTasks is now in sorted, affiliated order.
7429
7430            for (int i=0; i<N && maxNum > 0; i++) {
7431                TaskRecord tr = mRecentTasks.get(i);
7432                // Only add calling user or related users recent tasks
7433                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7434
7435                // Return the entry if desired by the caller.  We always return
7436                // the first entry, because callers always expect this to be the
7437                // foreground app.  We may filter others if the caller has
7438                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7439                // we should exclude the entry.
7440
7441                if (i == 0
7442                        || withExcluded
7443                        || (tr.intent == null)
7444                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7445                                == 0)) {
7446                    if (!allowed) {
7447                        // If the caller doesn't have the GET_TASKS permission, then only
7448                        // allow them to see a small subset of tasks -- their own and home.
7449                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7450                            continue;
7451                        }
7452                    }
7453                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7454                        // Don't include auto remove tasks that are finished or finishing.
7455                        continue;
7456                    }
7457
7458                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7459                    if (!detailed) {
7460                        rti.baseIntent.replaceExtras((Bundle)null);
7461                    }
7462
7463                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7464                        // Check whether this activity is currently available.
7465                        try {
7466                            if (rti.origActivity != null) {
7467                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7468                                        == null) {
7469                                    continue;
7470                                }
7471                            } else if (rti.baseIntent != null) {
7472                                if (pm.queryIntentActivities(rti.baseIntent,
7473                                        null, 0, userId) == null) {
7474                                    continue;
7475                                }
7476                            }
7477                        } catch (RemoteException e) {
7478                            // Will never happen.
7479                        }
7480                    }
7481
7482                    res.add(rti);
7483                    maxNum--;
7484                }
7485            }
7486            return res;
7487        }
7488    }
7489
7490    private TaskRecord recentTaskForIdLocked(int id) {
7491        final int N = mRecentTasks.size();
7492            for (int i=0; i<N; i++) {
7493                TaskRecord tr = mRecentTasks.get(i);
7494                if (tr.taskId == id) {
7495                    return tr;
7496                }
7497            }
7498            return null;
7499    }
7500
7501    @Override
7502    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7503        synchronized (this) {
7504            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7505                    "getTaskThumbnail()");
7506            TaskRecord tr = recentTaskForIdLocked(id);
7507            if (tr != null) {
7508                return tr.getTaskThumbnailLocked();
7509            }
7510        }
7511        return null;
7512    }
7513
7514    @Override
7515    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7516        synchronized (this) {
7517            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7518            if (r != null) {
7519                r.taskDescription = td;
7520                r.task.updateTaskDescription();
7521            }
7522        }
7523    }
7524
7525    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7526        if (!pr.killedByAm) {
7527            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7528            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7529                    pr.processName, pr.setAdj, reason);
7530            pr.killedByAm = true;
7531            Process.killProcessQuiet(pr.pid);
7532            Process.killProcessGroup(pr.info.uid, pr.pid);
7533        }
7534    }
7535
7536    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7537        tr.disposeThumbnail();
7538        mRecentTasks.remove(tr);
7539        tr.closeRecentsChain();
7540        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7541        Intent baseIntent = new Intent(
7542                tr.intent != null ? tr.intent : tr.affinityIntent);
7543        ComponentName component = baseIntent.getComponent();
7544        if (component == null) {
7545            Slog.w(TAG, "Now component for base intent of task: " + tr);
7546            return;
7547        }
7548
7549        // Find any running services associated with this app.
7550        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7551
7552        if (killProcesses) {
7553            // Find any running processes associated with this app.
7554            final String pkg = component.getPackageName();
7555            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7556            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7557            for (int i=0; i<pmap.size(); i++) {
7558                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7559                for (int j=0; j<uids.size(); j++) {
7560                    ProcessRecord proc = uids.valueAt(j);
7561                    if (proc.userId != tr.userId) {
7562                        continue;
7563                    }
7564                    if (!proc.pkgList.containsKey(pkg)) {
7565                        continue;
7566                    }
7567                    procs.add(proc);
7568                }
7569            }
7570
7571            // Kill the running processes.
7572            for (int i=0; i<procs.size(); i++) {
7573                ProcessRecord pr = procs.get(i);
7574                if (pr == mHomeProcess) {
7575                    // Don't kill the home process along with tasks from the same package.
7576                    continue;
7577                }
7578                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7579                    killUnneededProcessLocked(pr, "remove task");
7580                } else {
7581                    pr.waitingToKill = "remove task";
7582                }
7583            }
7584        }
7585    }
7586
7587    /**
7588     * Removes the task with the specified task id.
7589     *
7590     * @param taskId Identifier of the task to be removed.
7591     * @param flags Additional operational flags.  May be 0 or
7592     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7593     * @return Returns true if the given task was found and removed.
7594     */
7595    private boolean removeTaskByIdLocked(int taskId, int flags) {
7596        TaskRecord tr = recentTaskForIdLocked(taskId);
7597        if (tr != null) {
7598            tr.removeTaskActivitiesLocked();
7599            cleanUpRemovedTaskLocked(tr, flags);
7600            if (tr.isPersistable) {
7601                notifyTaskPersisterLocked(tr, true);
7602            }
7603            return true;
7604        }
7605        return false;
7606    }
7607
7608    @Override
7609    public boolean removeTask(int taskId, int flags) {
7610        synchronized (this) {
7611            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7612                    "removeTask()");
7613            long ident = Binder.clearCallingIdentity();
7614            try {
7615                return removeTaskByIdLocked(taskId, flags);
7616            } finally {
7617                Binder.restoreCallingIdentity(ident);
7618            }
7619        }
7620    }
7621
7622    /**
7623     * TODO: Add mController hook
7624     */
7625    @Override
7626    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7627        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7628                "moveTaskToFront()");
7629
7630        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7631        synchronized(this) {
7632            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7633                    Binder.getCallingUid(), "Task to front")) {
7634                ActivityOptions.abort(options);
7635                return;
7636            }
7637            final long origId = Binder.clearCallingIdentity();
7638            try {
7639                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7640                if (task == null) {
7641                    return;
7642                }
7643                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7644                    mStackSupervisor.showLockTaskToast();
7645                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7646                    return;
7647                }
7648                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7649                if (prev != null && prev.isRecentsActivity()) {
7650                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7651                }
7652                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7653            } finally {
7654                Binder.restoreCallingIdentity(origId);
7655            }
7656            ActivityOptions.abort(options);
7657        }
7658    }
7659
7660    @Override
7661    public void moveTaskToBack(int taskId) {
7662        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7663                "moveTaskToBack()");
7664
7665        synchronized(this) {
7666            TaskRecord tr = recentTaskForIdLocked(taskId);
7667            if (tr != null) {
7668                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7669                ActivityStack stack = tr.stack;
7670                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7671                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7672                            Binder.getCallingUid(), "Task to back")) {
7673                        return;
7674                    }
7675                }
7676                final long origId = Binder.clearCallingIdentity();
7677                try {
7678                    stack.moveTaskToBackLocked(taskId, null);
7679                } finally {
7680                    Binder.restoreCallingIdentity(origId);
7681                }
7682            }
7683        }
7684    }
7685
7686    /**
7687     * Moves an activity, and all of the other activities within the same task, to the bottom
7688     * of the history stack.  The activity's order within the task is unchanged.
7689     *
7690     * @param token A reference to the activity we wish to move
7691     * @param nonRoot If false then this only works if the activity is the root
7692     *                of a task; if true it will work for any activity in a task.
7693     * @return Returns true if the move completed, false if not.
7694     */
7695    @Override
7696    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7697        enforceNotIsolatedCaller("moveActivityTaskToBack");
7698        synchronized(this) {
7699            final long origId = Binder.clearCallingIdentity();
7700            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7701            if (taskId >= 0) {
7702                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7703            }
7704            Binder.restoreCallingIdentity(origId);
7705        }
7706        return false;
7707    }
7708
7709    @Override
7710    public void moveTaskBackwards(int task) {
7711        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7712                "moveTaskBackwards()");
7713
7714        synchronized(this) {
7715            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7716                    Binder.getCallingUid(), "Task backwards")) {
7717                return;
7718            }
7719            final long origId = Binder.clearCallingIdentity();
7720            moveTaskBackwardsLocked(task);
7721            Binder.restoreCallingIdentity(origId);
7722        }
7723    }
7724
7725    private final void moveTaskBackwardsLocked(int task) {
7726        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7727    }
7728
7729    @Override
7730    public IBinder getHomeActivityToken() throws RemoteException {
7731        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7732                "getHomeActivityToken()");
7733        synchronized (this) {
7734            return mStackSupervisor.getHomeActivityToken();
7735        }
7736    }
7737
7738    @Override
7739    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7740            IActivityContainerCallback callback) throws RemoteException {
7741        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7742                "createActivityContainer()");
7743        synchronized (this) {
7744            if (parentActivityToken == null) {
7745                throw new IllegalArgumentException("parent token must not be null");
7746            }
7747            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7748            if (r == null) {
7749                return null;
7750            }
7751            if (callback == null) {
7752                throw new IllegalArgumentException("callback must not be null");
7753            }
7754            return mStackSupervisor.createActivityContainer(r, callback);
7755        }
7756    }
7757
7758    @Override
7759    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7760        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7761                "deleteActivityContainer()");
7762        synchronized (this) {
7763            mStackSupervisor.deleteActivityContainer(container);
7764        }
7765    }
7766
7767    @Override
7768    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7769            throws RemoteException {
7770        synchronized (this) {
7771            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7772            if (stack != null) {
7773                return stack.mActivityContainer;
7774            }
7775            return null;
7776        }
7777    }
7778
7779    @Override
7780    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7781        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7782                "moveTaskToStack()");
7783        if (stackId == HOME_STACK_ID) {
7784            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7785                    new RuntimeException("here").fillInStackTrace());
7786        }
7787        synchronized (this) {
7788            long ident = Binder.clearCallingIdentity();
7789            try {
7790                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7791                        + stackId + " toTop=" + toTop);
7792                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7793            } finally {
7794                Binder.restoreCallingIdentity(ident);
7795            }
7796        }
7797    }
7798
7799    @Override
7800    public void resizeStack(int stackBoxId, Rect bounds) {
7801        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7802                "resizeStackBox()");
7803        long ident = Binder.clearCallingIdentity();
7804        try {
7805            mWindowManager.resizeStack(stackBoxId, bounds);
7806        } finally {
7807            Binder.restoreCallingIdentity(ident);
7808        }
7809    }
7810
7811    @Override
7812    public List<StackInfo> getAllStackInfos() {
7813        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7814                "getAllStackInfos()");
7815        long ident = Binder.clearCallingIdentity();
7816        try {
7817            synchronized (this) {
7818                return mStackSupervisor.getAllStackInfosLocked();
7819            }
7820        } finally {
7821            Binder.restoreCallingIdentity(ident);
7822        }
7823    }
7824
7825    @Override
7826    public StackInfo getStackInfo(int stackId) {
7827        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7828                "getStackInfo()");
7829        long ident = Binder.clearCallingIdentity();
7830        try {
7831            synchronized (this) {
7832                return mStackSupervisor.getStackInfoLocked(stackId);
7833            }
7834        } finally {
7835            Binder.restoreCallingIdentity(ident);
7836        }
7837    }
7838
7839    @Override
7840    public boolean isInHomeStack(int taskId) {
7841        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7842                "getStackInfo()");
7843        long ident = Binder.clearCallingIdentity();
7844        try {
7845            synchronized (this) {
7846                TaskRecord tr = recentTaskForIdLocked(taskId);
7847                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7848            }
7849        } finally {
7850            Binder.restoreCallingIdentity(ident);
7851        }
7852    }
7853
7854    @Override
7855    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7856        synchronized(this) {
7857            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7858        }
7859    }
7860
7861    private boolean isLockTaskAuthorized(String pkg) {
7862        final DevicePolicyManager dpm = (DevicePolicyManager)
7863                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7864        try {
7865            int uid = mContext.getPackageManager().getPackageUid(pkg,
7866                    Binder.getCallingUserHandle().getIdentifier());
7867            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7868        } catch (NameNotFoundException e) {
7869            return false;
7870        }
7871    }
7872
7873    void startLockTaskMode(TaskRecord task) {
7874        final String pkg;
7875        synchronized (this) {
7876            pkg = task.intent.getComponent().getPackageName();
7877        }
7878        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7879        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7880            final TaskRecord taskRecord = task;
7881            mHandler.post(new Runnable() {
7882                @Override
7883                public void run() {
7884                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7885                }
7886            });
7887            return;
7888        }
7889        long ident = Binder.clearCallingIdentity();
7890        try {
7891            synchronized (this) {
7892                // Since we lost lock on task, make sure it is still there.
7893                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7894                if (task != null) {
7895                    if (!isSystemInitiated
7896                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7897                        throw new IllegalArgumentException("Invalid task, not in foreground");
7898                    }
7899                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7900                }
7901            }
7902        } finally {
7903            Binder.restoreCallingIdentity(ident);
7904        }
7905    }
7906
7907    @Override
7908    public void startLockTaskMode(int taskId) {
7909        final TaskRecord task;
7910        long ident = Binder.clearCallingIdentity();
7911        try {
7912            synchronized (this) {
7913                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7914            }
7915        } finally {
7916            Binder.restoreCallingIdentity(ident);
7917        }
7918        if (task != null) {
7919            startLockTaskMode(task);
7920        }
7921    }
7922
7923    @Override
7924    public void startLockTaskMode(IBinder token) {
7925        final TaskRecord task;
7926        long ident = Binder.clearCallingIdentity();
7927        try {
7928            synchronized (this) {
7929                final ActivityRecord r = ActivityRecord.forToken(token);
7930                if (r == null) {
7931                    return;
7932                }
7933                task = r.task;
7934            }
7935        } finally {
7936            Binder.restoreCallingIdentity(ident);
7937        }
7938        if (task != null) {
7939            startLockTaskMode(task);
7940        }
7941    }
7942
7943    @Override
7944    public void startLockTaskModeOnCurrent() throws RemoteException {
7945        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7946        ActivityRecord r = null;
7947        synchronized (this) {
7948            r = mStackSupervisor.topRunningActivityLocked();
7949        }
7950        startLockTaskMode(r.task);
7951    }
7952
7953    @Override
7954    public void stopLockTaskMode() {
7955        // Verify that the user matches the package of the intent for the TaskRecord
7956        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7957        // and stopLockTaskMode.
7958        final int callingUid = Binder.getCallingUid();
7959        if (callingUid != Process.SYSTEM_UID) {
7960            try {
7961                String pkg =
7962                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7963                int uid = mContext.getPackageManager().getPackageUid(pkg,
7964                        Binder.getCallingUserHandle().getIdentifier());
7965                if (uid != callingUid) {
7966                    throw new SecurityException("Invalid uid, expected " + uid);
7967                }
7968            } catch (NameNotFoundException e) {
7969                Log.d(TAG, "stopLockTaskMode " + e);
7970                return;
7971            }
7972        }
7973        long ident = Binder.clearCallingIdentity();
7974        try {
7975            Log.d(TAG, "stopLockTaskMode");
7976            // Stop lock task
7977            synchronized (this) {
7978                mStackSupervisor.setLockTaskModeLocked(null, false);
7979            }
7980        } finally {
7981            Binder.restoreCallingIdentity(ident);
7982        }
7983    }
7984
7985    @Override
7986    public void stopLockTaskModeOnCurrent() throws RemoteException {
7987        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7988        long ident = Binder.clearCallingIdentity();
7989        try {
7990            stopLockTaskMode();
7991        } finally {
7992            Binder.restoreCallingIdentity(ident);
7993        }
7994    }
7995
7996    @Override
7997    public boolean isInLockTaskMode() {
7998        synchronized (this) {
7999            return mStackSupervisor.isInLockTaskMode();
8000        }
8001    }
8002
8003    // =========================================================
8004    // CONTENT PROVIDERS
8005    // =========================================================
8006
8007    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8008        List<ProviderInfo> providers = null;
8009        try {
8010            providers = AppGlobals.getPackageManager().
8011                queryContentProviders(app.processName, app.uid,
8012                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8013        } catch (RemoteException ex) {
8014        }
8015        if (DEBUG_MU)
8016            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8017        int userId = app.userId;
8018        if (providers != null) {
8019            int N = providers.size();
8020            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8021            for (int i=0; i<N; i++) {
8022                ProviderInfo cpi =
8023                    (ProviderInfo)providers.get(i);
8024                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8025                        cpi.name, cpi.flags);
8026                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8027                    // This is a singleton provider, but a user besides the
8028                    // default user is asking to initialize a process it runs
8029                    // in...  well, no, it doesn't actually run in this process,
8030                    // it runs in the process of the default user.  Get rid of it.
8031                    providers.remove(i);
8032                    N--;
8033                    i--;
8034                    continue;
8035                }
8036
8037                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8038                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8039                if (cpr == null) {
8040                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8041                    mProviderMap.putProviderByClass(comp, cpr);
8042                }
8043                if (DEBUG_MU)
8044                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8045                app.pubProviders.put(cpi.name, cpr);
8046                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8047                    // Don't add this if it is a platform component that is marked
8048                    // to run in multiple processes, because this is actually
8049                    // part of the framework so doesn't make sense to track as a
8050                    // separate apk in the process.
8051                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8052                            mProcessStats);
8053                }
8054                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8055            }
8056        }
8057        return providers;
8058    }
8059
8060    /**
8061     * Check if {@link ProcessRecord} has a possible chance at accessing the
8062     * given {@link ProviderInfo}. Final permission checking is always done
8063     * in {@link ContentProvider}.
8064     */
8065    private final String checkContentProviderPermissionLocked(
8066            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8067        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8068        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8069        boolean checkedGrants = false;
8070        if (checkUser) {
8071            // Looking for cross-user grants before enforcing the typical cross-users permissions
8072            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8073            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8074                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8075                    return null;
8076                }
8077                checkedGrants = true;
8078            }
8079            userId = handleIncomingUser(callingPid, callingUid, userId,
8080                    false, ALLOW_NON_FULL,
8081                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8082            if (userId != tmpTargetUserId) {
8083                // When we actually went to determine the final targer user ID, this ended
8084                // up different than our initial check for the authority.  This is because
8085                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8086                // SELF.  So we need to re-check the grants again.
8087                checkedGrants = false;
8088            }
8089        }
8090        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8091                cpi.applicationInfo.uid, cpi.exported)
8092                == PackageManager.PERMISSION_GRANTED) {
8093            return null;
8094        }
8095        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8096                cpi.applicationInfo.uid, cpi.exported)
8097                == PackageManager.PERMISSION_GRANTED) {
8098            return null;
8099        }
8100
8101        PathPermission[] pps = cpi.pathPermissions;
8102        if (pps != null) {
8103            int i = pps.length;
8104            while (i > 0) {
8105                i--;
8106                PathPermission pp = pps[i];
8107                String pprperm = pp.getReadPermission();
8108                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8109                        cpi.applicationInfo.uid, cpi.exported)
8110                        == PackageManager.PERMISSION_GRANTED) {
8111                    return null;
8112                }
8113                String ppwperm = pp.getWritePermission();
8114                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8115                        cpi.applicationInfo.uid, cpi.exported)
8116                        == PackageManager.PERMISSION_GRANTED) {
8117                    return null;
8118                }
8119            }
8120        }
8121        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8122            return null;
8123        }
8124
8125        String msg;
8126        if (!cpi.exported) {
8127            msg = "Permission Denial: opening provider " + cpi.name
8128                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8129                    + ", uid=" + callingUid + ") that is not exported from uid "
8130                    + cpi.applicationInfo.uid;
8131        } else {
8132            msg = "Permission Denial: opening provider " + cpi.name
8133                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8134                    + ", uid=" + callingUid + ") requires "
8135                    + cpi.readPermission + " or " + cpi.writePermission;
8136        }
8137        Slog.w(TAG, msg);
8138        return msg;
8139    }
8140
8141    /**
8142     * Returns if the ContentProvider has granted a uri to callingUid
8143     */
8144    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8145        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8146        if (perms != null) {
8147            for (int i=perms.size()-1; i>=0; i--) {
8148                GrantUri grantUri = perms.keyAt(i);
8149                if (grantUri.sourceUserId == userId || !checkUser) {
8150                    if (matchesProvider(grantUri.uri, cpi)) {
8151                        return true;
8152                    }
8153                }
8154            }
8155        }
8156        return false;
8157    }
8158
8159    /**
8160     * Returns true if the uri authority is one of the authorities specified in the provider.
8161     */
8162    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8163        String uriAuth = uri.getAuthority();
8164        String cpiAuth = cpi.authority;
8165        if (cpiAuth.indexOf(';') == -1) {
8166            return cpiAuth.equals(uriAuth);
8167        }
8168        String[] cpiAuths = cpiAuth.split(";");
8169        int length = cpiAuths.length;
8170        for (int i = 0; i < length; i++) {
8171            if (cpiAuths[i].equals(uriAuth)) return true;
8172        }
8173        return false;
8174    }
8175
8176    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8177            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8178        if (r != null) {
8179            for (int i=0; i<r.conProviders.size(); i++) {
8180                ContentProviderConnection conn = r.conProviders.get(i);
8181                if (conn.provider == cpr) {
8182                    if (DEBUG_PROVIDER) Slog.v(TAG,
8183                            "Adding provider requested by "
8184                            + r.processName + " from process "
8185                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8186                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8187                    if (stable) {
8188                        conn.stableCount++;
8189                        conn.numStableIncs++;
8190                    } else {
8191                        conn.unstableCount++;
8192                        conn.numUnstableIncs++;
8193                    }
8194                    return conn;
8195                }
8196            }
8197            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8198            if (stable) {
8199                conn.stableCount = 1;
8200                conn.numStableIncs = 1;
8201            } else {
8202                conn.unstableCount = 1;
8203                conn.numUnstableIncs = 1;
8204            }
8205            cpr.connections.add(conn);
8206            r.conProviders.add(conn);
8207            return conn;
8208        }
8209        cpr.addExternalProcessHandleLocked(externalProcessToken);
8210        return null;
8211    }
8212
8213    boolean decProviderCountLocked(ContentProviderConnection conn,
8214            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8215        if (conn != null) {
8216            cpr = conn.provider;
8217            if (DEBUG_PROVIDER) Slog.v(TAG,
8218                    "Removing provider requested by "
8219                    + conn.client.processName + " from process "
8220                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8221                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8222            if (stable) {
8223                conn.stableCount--;
8224            } else {
8225                conn.unstableCount--;
8226            }
8227            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8228                cpr.connections.remove(conn);
8229                conn.client.conProviders.remove(conn);
8230                return true;
8231            }
8232            return false;
8233        }
8234        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8235        return false;
8236    }
8237
8238    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8239            String name, IBinder token, boolean stable, int userId) {
8240        ContentProviderRecord cpr;
8241        ContentProviderConnection conn = null;
8242        ProviderInfo cpi = null;
8243
8244        synchronized(this) {
8245            ProcessRecord r = null;
8246            if (caller != null) {
8247                r = getRecordForAppLocked(caller);
8248                if (r == null) {
8249                    throw new SecurityException(
8250                            "Unable to find app for caller " + caller
8251                          + " (pid=" + Binder.getCallingPid()
8252                          + ") when getting content provider " + name);
8253                }
8254            }
8255
8256            boolean checkCrossUser = true;
8257
8258            // First check if this content provider has been published...
8259            cpr = mProviderMap.getProviderByName(name, userId);
8260            // If that didn't work, check if it exists for user 0 and then
8261            // verify that it's a singleton provider before using it.
8262            if (cpr == null && userId != UserHandle.USER_OWNER) {
8263                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8264                if (cpr != null) {
8265                    cpi = cpr.info;
8266                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8267                            cpi.name, cpi.flags)
8268                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8269                        userId = UserHandle.USER_OWNER;
8270                        checkCrossUser = false;
8271                    } else {
8272                        cpr = null;
8273                        cpi = null;
8274                    }
8275                }
8276            }
8277
8278            boolean providerRunning = cpr != null;
8279            if (providerRunning) {
8280                cpi = cpr.info;
8281                String msg;
8282                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8283                        != null) {
8284                    throw new SecurityException(msg);
8285                }
8286
8287                if (r != null && cpr.canRunHere(r)) {
8288                    // This provider has been published or is in the process
8289                    // of being published...  but it is also allowed to run
8290                    // in the caller's process, so don't make a connection
8291                    // and just let the caller instantiate its own instance.
8292                    ContentProviderHolder holder = cpr.newHolder(null);
8293                    // don't give caller the provider object, it needs
8294                    // to make its own.
8295                    holder.provider = null;
8296                    return holder;
8297                }
8298
8299                final long origId = Binder.clearCallingIdentity();
8300
8301                // In this case the provider instance already exists, so we can
8302                // return it right away.
8303                conn = incProviderCountLocked(r, cpr, token, stable);
8304                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8305                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8306                        // If this is a perceptible app accessing the provider,
8307                        // make sure to count it as being accessed and thus
8308                        // back up on the LRU list.  This is good because
8309                        // content providers are often expensive to start.
8310                        updateLruProcessLocked(cpr.proc, false, null);
8311                    }
8312                }
8313
8314                if (cpr.proc != null) {
8315                    if (false) {
8316                        if (cpr.name.flattenToShortString().equals(
8317                                "com.android.providers.calendar/.CalendarProvider2")) {
8318                            Slog.v(TAG, "****************** KILLING "
8319                                + cpr.name.flattenToShortString());
8320                            Process.killProcess(cpr.proc.pid);
8321                        }
8322                    }
8323                    boolean success = updateOomAdjLocked(cpr.proc);
8324                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8325                    // NOTE: there is still a race here where a signal could be
8326                    // pending on the process even though we managed to update its
8327                    // adj level.  Not sure what to do about this, but at least
8328                    // the race is now smaller.
8329                    if (!success) {
8330                        // Uh oh...  it looks like the provider's process
8331                        // has been killed on us.  We need to wait for a new
8332                        // process to be started, and make sure its death
8333                        // doesn't kill our process.
8334                        Slog.i(TAG,
8335                                "Existing provider " + cpr.name.flattenToShortString()
8336                                + " is crashing; detaching " + r);
8337                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8338                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8339                        if (!lastRef) {
8340                            // This wasn't the last ref our process had on
8341                            // the provider...  we have now been killed, bail.
8342                            return null;
8343                        }
8344                        providerRunning = false;
8345                        conn = null;
8346                    }
8347                }
8348
8349                Binder.restoreCallingIdentity(origId);
8350            }
8351
8352            boolean singleton;
8353            if (!providerRunning) {
8354                try {
8355                    cpi = AppGlobals.getPackageManager().
8356                        resolveContentProvider(name,
8357                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8358                } catch (RemoteException ex) {
8359                }
8360                if (cpi == null) {
8361                    return null;
8362                }
8363                // If the provider is a singleton AND
8364                // (it's a call within the same user || the provider is a
8365                // privileged app)
8366                // Then allow connecting to the singleton provider
8367                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8368                        cpi.name, cpi.flags)
8369                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8370                if (singleton) {
8371                    userId = UserHandle.USER_OWNER;
8372                }
8373                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8374
8375                String msg;
8376                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8377                        != null) {
8378                    throw new SecurityException(msg);
8379                }
8380
8381                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8382                        && !cpi.processName.equals("system")) {
8383                    // If this content provider does not run in the system
8384                    // process, and the system is not yet ready to run other
8385                    // processes, then fail fast instead of hanging.
8386                    throw new IllegalArgumentException(
8387                            "Attempt to launch content provider before system ready");
8388                }
8389
8390                // Make sure that the user who owns this provider is started.  If not,
8391                // we don't want to allow it to run.
8392                if (mStartedUsers.get(userId) == null) {
8393                    Slog.w(TAG, "Unable to launch app "
8394                            + cpi.applicationInfo.packageName + "/"
8395                            + cpi.applicationInfo.uid + " for provider "
8396                            + name + ": user " + userId + " is stopped");
8397                    return null;
8398                }
8399
8400                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8401                cpr = mProviderMap.getProviderByClass(comp, userId);
8402                final boolean firstClass = cpr == null;
8403                if (firstClass) {
8404                    try {
8405                        ApplicationInfo ai =
8406                            AppGlobals.getPackageManager().
8407                                getApplicationInfo(
8408                                        cpi.applicationInfo.packageName,
8409                                        STOCK_PM_FLAGS, userId);
8410                        if (ai == null) {
8411                            Slog.w(TAG, "No package info for content provider "
8412                                    + cpi.name);
8413                            return null;
8414                        }
8415                        ai = getAppInfoForUser(ai, userId);
8416                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8417                    } catch (RemoteException ex) {
8418                        // pm is in same process, this will never happen.
8419                    }
8420                }
8421
8422                if (r != null && cpr.canRunHere(r)) {
8423                    // If this is a multiprocess provider, then just return its
8424                    // info and allow the caller to instantiate it.  Only do
8425                    // this if the provider is the same user as the caller's
8426                    // process, or can run as root (so can be in any process).
8427                    return cpr.newHolder(null);
8428                }
8429
8430                if (DEBUG_PROVIDER) {
8431                    RuntimeException e = new RuntimeException("here");
8432                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8433                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8434                }
8435
8436                // This is single process, and our app is now connecting to it.
8437                // See if we are already in the process of launching this
8438                // provider.
8439                final int N = mLaunchingProviders.size();
8440                int i;
8441                for (i=0; i<N; i++) {
8442                    if (mLaunchingProviders.get(i) == cpr) {
8443                        break;
8444                    }
8445                }
8446
8447                // If the provider is not already being launched, then get it
8448                // started.
8449                if (i >= N) {
8450                    final long origId = Binder.clearCallingIdentity();
8451
8452                    try {
8453                        // Content provider is now in use, its package can't be stopped.
8454                        try {
8455                            AppGlobals.getPackageManager().setPackageStoppedState(
8456                                    cpr.appInfo.packageName, false, userId);
8457                        } catch (RemoteException e) {
8458                        } catch (IllegalArgumentException e) {
8459                            Slog.w(TAG, "Failed trying to unstop package "
8460                                    + cpr.appInfo.packageName + ": " + e);
8461                        }
8462
8463                        // Use existing process if already started
8464                        ProcessRecord proc = getProcessRecordLocked(
8465                                cpi.processName, cpr.appInfo.uid, false);
8466                        if (proc != null && proc.thread != null) {
8467                            if (DEBUG_PROVIDER) {
8468                                Slog.d(TAG, "Installing in existing process " + proc);
8469                            }
8470                            proc.pubProviders.put(cpi.name, cpr);
8471                            try {
8472                                proc.thread.scheduleInstallProvider(cpi);
8473                            } catch (RemoteException e) {
8474                            }
8475                        } else {
8476                            proc = startProcessLocked(cpi.processName,
8477                                    cpr.appInfo, false, 0, "content provider",
8478                                    new ComponentName(cpi.applicationInfo.packageName,
8479                                            cpi.name), false, false, false);
8480                            if (proc == null) {
8481                                Slog.w(TAG, "Unable to launch app "
8482                                        + cpi.applicationInfo.packageName + "/"
8483                                        + cpi.applicationInfo.uid + " for provider "
8484                                        + name + ": process is bad");
8485                                return null;
8486                            }
8487                        }
8488                        cpr.launchingApp = proc;
8489                        mLaunchingProviders.add(cpr);
8490                    } finally {
8491                        Binder.restoreCallingIdentity(origId);
8492                    }
8493                }
8494
8495                // Make sure the provider is published (the same provider class
8496                // may be published under multiple names).
8497                if (firstClass) {
8498                    mProviderMap.putProviderByClass(comp, cpr);
8499                }
8500
8501                mProviderMap.putProviderByName(name, cpr);
8502                conn = incProviderCountLocked(r, cpr, token, stable);
8503                if (conn != null) {
8504                    conn.waiting = true;
8505                }
8506            }
8507        }
8508
8509        // Wait for the provider to be published...
8510        synchronized (cpr) {
8511            while (cpr.provider == null) {
8512                if (cpr.launchingApp == null) {
8513                    Slog.w(TAG, "Unable to launch app "
8514                            + cpi.applicationInfo.packageName + "/"
8515                            + cpi.applicationInfo.uid + " for provider "
8516                            + name + ": launching app became null");
8517                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8518                            UserHandle.getUserId(cpi.applicationInfo.uid),
8519                            cpi.applicationInfo.packageName,
8520                            cpi.applicationInfo.uid, name);
8521                    return null;
8522                }
8523                try {
8524                    if (DEBUG_MU) {
8525                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8526                                + cpr.launchingApp);
8527                    }
8528                    if (conn != null) {
8529                        conn.waiting = true;
8530                    }
8531                    cpr.wait();
8532                } catch (InterruptedException ex) {
8533                } finally {
8534                    if (conn != null) {
8535                        conn.waiting = false;
8536                    }
8537                }
8538            }
8539        }
8540        return cpr != null ? cpr.newHolder(conn) : null;
8541    }
8542
8543    @Override
8544    public final ContentProviderHolder getContentProvider(
8545            IApplicationThread caller, String name, int userId, boolean stable) {
8546        enforceNotIsolatedCaller("getContentProvider");
8547        if (caller == null) {
8548            String msg = "null IApplicationThread when getting content provider "
8549                    + name;
8550            Slog.w(TAG, msg);
8551            throw new SecurityException(msg);
8552        }
8553        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8554        // with cross-user grant.
8555        return getContentProviderImpl(caller, name, null, stable, userId);
8556    }
8557
8558    public ContentProviderHolder getContentProviderExternal(
8559            String name, int userId, IBinder token) {
8560        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8561            "Do not have permission in call getContentProviderExternal()");
8562        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8563                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8564        return getContentProviderExternalUnchecked(name, token, userId);
8565    }
8566
8567    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8568            IBinder token, int userId) {
8569        return getContentProviderImpl(null, name, token, true, userId);
8570    }
8571
8572    /**
8573     * Drop a content provider from a ProcessRecord's bookkeeping
8574     */
8575    public void removeContentProvider(IBinder connection, boolean stable) {
8576        enforceNotIsolatedCaller("removeContentProvider");
8577        long ident = Binder.clearCallingIdentity();
8578        try {
8579            synchronized (this) {
8580                ContentProviderConnection conn;
8581                try {
8582                    conn = (ContentProviderConnection)connection;
8583                } catch (ClassCastException e) {
8584                    String msg ="removeContentProvider: " + connection
8585                            + " not a ContentProviderConnection";
8586                    Slog.w(TAG, msg);
8587                    throw new IllegalArgumentException(msg);
8588                }
8589                if (conn == null) {
8590                    throw new NullPointerException("connection is null");
8591                }
8592                if (decProviderCountLocked(conn, null, null, stable)) {
8593                    updateOomAdjLocked();
8594                }
8595            }
8596        } finally {
8597            Binder.restoreCallingIdentity(ident);
8598        }
8599    }
8600
8601    public void removeContentProviderExternal(String name, IBinder token) {
8602        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8603            "Do not have permission in call removeContentProviderExternal()");
8604        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8605    }
8606
8607    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8608        synchronized (this) {
8609            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8610            if(cpr == null) {
8611                //remove from mProvidersByClass
8612                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8613                return;
8614            }
8615
8616            //update content provider record entry info
8617            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8618            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8619            if (localCpr.hasExternalProcessHandles()) {
8620                if (localCpr.removeExternalProcessHandleLocked(token)) {
8621                    updateOomAdjLocked();
8622                } else {
8623                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8624                            + " with no external reference for token: "
8625                            + token + ".");
8626                }
8627            } else {
8628                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8629                        + " with no external references.");
8630            }
8631        }
8632    }
8633
8634    public final void publishContentProviders(IApplicationThread caller,
8635            List<ContentProviderHolder> providers) {
8636        if (providers == null) {
8637            return;
8638        }
8639
8640        enforceNotIsolatedCaller("publishContentProviders");
8641        synchronized (this) {
8642            final ProcessRecord r = getRecordForAppLocked(caller);
8643            if (DEBUG_MU)
8644                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8645            if (r == null) {
8646                throw new SecurityException(
8647                        "Unable to find app for caller " + caller
8648                      + " (pid=" + Binder.getCallingPid()
8649                      + ") when publishing content providers");
8650            }
8651
8652            final long origId = Binder.clearCallingIdentity();
8653
8654            final int N = providers.size();
8655            for (int i=0; i<N; i++) {
8656                ContentProviderHolder src = providers.get(i);
8657                if (src == null || src.info == null || src.provider == null) {
8658                    continue;
8659                }
8660                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8661                if (DEBUG_MU)
8662                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8663                if (dst != null) {
8664                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8665                    mProviderMap.putProviderByClass(comp, dst);
8666                    String names[] = dst.info.authority.split(";");
8667                    for (int j = 0; j < names.length; j++) {
8668                        mProviderMap.putProviderByName(names[j], dst);
8669                    }
8670
8671                    int NL = mLaunchingProviders.size();
8672                    int j;
8673                    for (j=0; j<NL; j++) {
8674                        if (mLaunchingProviders.get(j) == dst) {
8675                            mLaunchingProviders.remove(j);
8676                            j--;
8677                            NL--;
8678                        }
8679                    }
8680                    synchronized (dst) {
8681                        dst.provider = src.provider;
8682                        dst.proc = r;
8683                        dst.notifyAll();
8684                    }
8685                    updateOomAdjLocked(r);
8686                }
8687            }
8688
8689            Binder.restoreCallingIdentity(origId);
8690        }
8691    }
8692
8693    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8694        ContentProviderConnection conn;
8695        try {
8696            conn = (ContentProviderConnection)connection;
8697        } catch (ClassCastException e) {
8698            String msg ="refContentProvider: " + connection
8699                    + " not a ContentProviderConnection";
8700            Slog.w(TAG, msg);
8701            throw new IllegalArgumentException(msg);
8702        }
8703        if (conn == null) {
8704            throw new NullPointerException("connection is null");
8705        }
8706
8707        synchronized (this) {
8708            if (stable > 0) {
8709                conn.numStableIncs += stable;
8710            }
8711            stable = conn.stableCount + stable;
8712            if (stable < 0) {
8713                throw new IllegalStateException("stableCount < 0: " + stable);
8714            }
8715
8716            if (unstable > 0) {
8717                conn.numUnstableIncs += unstable;
8718            }
8719            unstable = conn.unstableCount + unstable;
8720            if (unstable < 0) {
8721                throw new IllegalStateException("unstableCount < 0: " + unstable);
8722            }
8723
8724            if ((stable+unstable) <= 0) {
8725                throw new IllegalStateException("ref counts can't go to zero here: stable="
8726                        + stable + " unstable=" + unstable);
8727            }
8728            conn.stableCount = stable;
8729            conn.unstableCount = unstable;
8730            return !conn.dead;
8731        }
8732    }
8733
8734    public void unstableProviderDied(IBinder connection) {
8735        ContentProviderConnection conn;
8736        try {
8737            conn = (ContentProviderConnection)connection;
8738        } catch (ClassCastException e) {
8739            String msg ="refContentProvider: " + connection
8740                    + " not a ContentProviderConnection";
8741            Slog.w(TAG, msg);
8742            throw new IllegalArgumentException(msg);
8743        }
8744        if (conn == null) {
8745            throw new NullPointerException("connection is null");
8746        }
8747
8748        // Safely retrieve the content provider associated with the connection.
8749        IContentProvider provider;
8750        synchronized (this) {
8751            provider = conn.provider.provider;
8752        }
8753
8754        if (provider == null) {
8755            // Um, yeah, we're way ahead of you.
8756            return;
8757        }
8758
8759        // Make sure the caller is being honest with us.
8760        if (provider.asBinder().pingBinder()) {
8761            // Er, no, still looks good to us.
8762            synchronized (this) {
8763                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8764                        + " says " + conn + " died, but we don't agree");
8765                return;
8766            }
8767        }
8768
8769        // Well look at that!  It's dead!
8770        synchronized (this) {
8771            if (conn.provider.provider != provider) {
8772                // But something changed...  good enough.
8773                return;
8774            }
8775
8776            ProcessRecord proc = conn.provider.proc;
8777            if (proc == null || proc.thread == null) {
8778                // Seems like the process is already cleaned up.
8779                return;
8780            }
8781
8782            // As far as we're concerned, this is just like receiving a
8783            // death notification...  just a bit prematurely.
8784            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8785                    + ") early provider death");
8786            final long ident = Binder.clearCallingIdentity();
8787            try {
8788                appDiedLocked(proc, proc.pid, proc.thread);
8789            } finally {
8790                Binder.restoreCallingIdentity(ident);
8791            }
8792        }
8793    }
8794
8795    @Override
8796    public void appNotRespondingViaProvider(IBinder connection) {
8797        enforceCallingPermission(
8798                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8799
8800        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8801        if (conn == null) {
8802            Slog.w(TAG, "ContentProviderConnection is null");
8803            return;
8804        }
8805
8806        final ProcessRecord host = conn.provider.proc;
8807        if (host == null) {
8808            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8809            return;
8810        }
8811
8812        final long token = Binder.clearCallingIdentity();
8813        try {
8814            appNotResponding(host, null, null, false, "ContentProvider not responding");
8815        } finally {
8816            Binder.restoreCallingIdentity(token);
8817        }
8818    }
8819
8820    public final void installSystemProviders() {
8821        List<ProviderInfo> providers;
8822        synchronized (this) {
8823            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8824            providers = generateApplicationProvidersLocked(app);
8825            if (providers != null) {
8826                for (int i=providers.size()-1; i>=0; i--) {
8827                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8828                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8829                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8830                                + ": not system .apk");
8831                        providers.remove(i);
8832                    }
8833                }
8834            }
8835        }
8836        if (providers != null) {
8837            mSystemThread.installSystemProviders(providers);
8838        }
8839
8840        mCoreSettingsObserver = new CoreSettingsObserver(this);
8841
8842        //mUsageStatsService.monitorPackages();
8843    }
8844
8845    /**
8846     * Allows app to retrieve the MIME type of a URI without having permission
8847     * to access its content provider.
8848     *
8849     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8850     *
8851     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8852     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8853     */
8854    public String getProviderMimeType(Uri uri, int userId) {
8855        enforceNotIsolatedCaller("getProviderMimeType");
8856        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8857                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8858        final String name = uri.getAuthority();
8859        final long ident = Binder.clearCallingIdentity();
8860        ContentProviderHolder holder = null;
8861
8862        try {
8863            holder = getContentProviderExternalUnchecked(name, null, userId);
8864            if (holder != null) {
8865                return holder.provider.getType(uri);
8866            }
8867        } catch (RemoteException e) {
8868            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8869            return null;
8870        } finally {
8871            if (holder != null) {
8872                removeContentProviderExternalUnchecked(name, null, userId);
8873            }
8874            Binder.restoreCallingIdentity(ident);
8875        }
8876
8877        return null;
8878    }
8879
8880    // =========================================================
8881    // GLOBAL MANAGEMENT
8882    // =========================================================
8883
8884    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8885            boolean isolated) {
8886        String proc = customProcess != null ? customProcess : info.processName;
8887        BatteryStatsImpl.Uid.Proc ps = null;
8888        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8889        int uid = info.uid;
8890        if (isolated) {
8891            int userId = UserHandle.getUserId(uid);
8892            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8893            while (true) {
8894                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8895                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8896                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8897                }
8898                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8899                mNextIsolatedProcessUid++;
8900                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8901                    // No process for this uid, use it.
8902                    break;
8903                }
8904                stepsLeft--;
8905                if (stepsLeft <= 0) {
8906                    return null;
8907                }
8908            }
8909        }
8910        return new ProcessRecord(stats, info, proc, uid);
8911    }
8912
8913    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8914            String abiOverride) {
8915        ProcessRecord app;
8916        if (!isolated) {
8917            app = getProcessRecordLocked(info.processName, info.uid, true);
8918        } else {
8919            app = null;
8920        }
8921
8922        if (app == null) {
8923            app = newProcessRecordLocked(info, null, isolated);
8924            mProcessNames.put(info.processName, app.uid, app);
8925            if (isolated) {
8926                mIsolatedProcesses.put(app.uid, app);
8927            }
8928            updateLruProcessLocked(app, false, null);
8929            updateOomAdjLocked();
8930        }
8931
8932        // This package really, really can not be stopped.
8933        try {
8934            AppGlobals.getPackageManager().setPackageStoppedState(
8935                    info.packageName, false, UserHandle.getUserId(app.uid));
8936        } catch (RemoteException e) {
8937        } catch (IllegalArgumentException e) {
8938            Slog.w(TAG, "Failed trying to unstop package "
8939                    + info.packageName + ": " + e);
8940        }
8941
8942        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8943                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8944            app.persistent = true;
8945            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8946        }
8947        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8948            mPersistentStartingProcesses.add(app);
8949            startProcessLocked(app, "added application", app.processName,
8950                    abiOverride);
8951        }
8952
8953        return app;
8954    }
8955
8956    public void unhandledBack() {
8957        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8958                "unhandledBack()");
8959
8960        synchronized(this) {
8961            final long origId = Binder.clearCallingIdentity();
8962            try {
8963                getFocusedStack().unhandledBackLocked();
8964            } finally {
8965                Binder.restoreCallingIdentity(origId);
8966            }
8967        }
8968    }
8969
8970    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8971        enforceNotIsolatedCaller("openContentUri");
8972        final int userId = UserHandle.getCallingUserId();
8973        String name = uri.getAuthority();
8974        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8975        ParcelFileDescriptor pfd = null;
8976        if (cph != null) {
8977            // We record the binder invoker's uid in thread-local storage before
8978            // going to the content provider to open the file.  Later, in the code
8979            // that handles all permissions checks, we look for this uid and use
8980            // that rather than the Activity Manager's own uid.  The effect is that
8981            // we do the check against the caller's permissions even though it looks
8982            // to the content provider like the Activity Manager itself is making
8983            // the request.
8984            sCallerIdentity.set(new Identity(
8985                    Binder.getCallingPid(), Binder.getCallingUid()));
8986            try {
8987                pfd = cph.provider.openFile(null, uri, "r", null);
8988            } catch (FileNotFoundException e) {
8989                // do nothing; pfd will be returned null
8990            } finally {
8991                // Ensure that whatever happens, we clean up the identity state
8992                sCallerIdentity.remove();
8993            }
8994
8995            // We've got the fd now, so we're done with the provider.
8996            removeContentProviderExternalUnchecked(name, null, userId);
8997        } else {
8998            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8999        }
9000        return pfd;
9001    }
9002
9003    // Actually is sleeping or shutting down or whatever else in the future
9004    // is an inactive state.
9005    public boolean isSleepingOrShuttingDown() {
9006        return mSleeping || mShuttingDown;
9007    }
9008
9009    public boolean isSleeping() {
9010        return mSleeping;
9011    }
9012
9013    void goingToSleep() {
9014        synchronized(this) {
9015            mWentToSleep = true;
9016            updateEventDispatchingLocked();
9017            goToSleepIfNeededLocked();
9018        }
9019    }
9020
9021    void finishRunningVoiceLocked() {
9022        if (mRunningVoice) {
9023            mRunningVoice = false;
9024            goToSleepIfNeededLocked();
9025        }
9026    }
9027
9028    void goToSleepIfNeededLocked() {
9029        if (mWentToSleep && !mRunningVoice) {
9030            if (!mSleeping) {
9031                mSleeping = true;
9032                mStackSupervisor.goingToSleepLocked();
9033
9034                // Initialize the wake times of all processes.
9035                checkExcessivePowerUsageLocked(false);
9036                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9037                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9038                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9039            }
9040        }
9041    }
9042
9043    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9044        mTaskPersister.notify(task, flush);
9045    }
9046
9047    @Override
9048    public boolean shutdown(int timeout) {
9049        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9050                != PackageManager.PERMISSION_GRANTED) {
9051            throw new SecurityException("Requires permission "
9052                    + android.Manifest.permission.SHUTDOWN);
9053        }
9054
9055        boolean timedout = false;
9056
9057        synchronized(this) {
9058            mShuttingDown = true;
9059            updateEventDispatchingLocked();
9060            timedout = mStackSupervisor.shutdownLocked(timeout);
9061        }
9062
9063        mAppOpsService.shutdown();
9064        if (mUsageStatsService != null) {
9065            mUsageStatsService.prepareShutdown();
9066        }
9067        mBatteryStatsService.shutdown();
9068        synchronized (this) {
9069            mProcessStats.shutdownLocked();
9070        }
9071        notifyTaskPersisterLocked(null, true);
9072
9073        return timedout;
9074    }
9075
9076    public final void activitySlept(IBinder token) {
9077        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9078
9079        final long origId = Binder.clearCallingIdentity();
9080
9081        synchronized (this) {
9082            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9083            if (r != null) {
9084                mStackSupervisor.activitySleptLocked(r);
9085            }
9086        }
9087
9088        Binder.restoreCallingIdentity(origId);
9089    }
9090
9091    void logLockScreen(String msg) {
9092        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9093                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9094                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9095                mStackSupervisor.mDismissKeyguardOnNextActivity);
9096    }
9097
9098    private void comeOutOfSleepIfNeededLocked() {
9099        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9100            if (mSleeping) {
9101                mSleeping = false;
9102                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9103            }
9104        }
9105    }
9106
9107    void wakingUp() {
9108        synchronized(this) {
9109            mWentToSleep = false;
9110            updateEventDispatchingLocked();
9111            comeOutOfSleepIfNeededLocked();
9112        }
9113    }
9114
9115    void startRunningVoiceLocked() {
9116        if (!mRunningVoice) {
9117            mRunningVoice = true;
9118            comeOutOfSleepIfNeededLocked();
9119        }
9120    }
9121
9122    private void updateEventDispatchingLocked() {
9123        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9124    }
9125
9126    public void setLockScreenShown(boolean shown) {
9127        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9128                != PackageManager.PERMISSION_GRANTED) {
9129            throw new SecurityException("Requires permission "
9130                    + android.Manifest.permission.DEVICE_POWER);
9131        }
9132
9133        synchronized(this) {
9134            long ident = Binder.clearCallingIdentity();
9135            try {
9136                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9137                mLockScreenShown = shown;
9138                comeOutOfSleepIfNeededLocked();
9139            } finally {
9140                Binder.restoreCallingIdentity(ident);
9141            }
9142        }
9143    }
9144
9145    @Override
9146    public void stopAppSwitches() {
9147        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9148                != PackageManager.PERMISSION_GRANTED) {
9149            throw new SecurityException("Requires permission "
9150                    + android.Manifest.permission.STOP_APP_SWITCHES);
9151        }
9152
9153        synchronized(this) {
9154            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9155                    + APP_SWITCH_DELAY_TIME;
9156            mDidAppSwitch = false;
9157            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9158            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9159            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9160        }
9161    }
9162
9163    public void resumeAppSwitches() {
9164        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9165                != PackageManager.PERMISSION_GRANTED) {
9166            throw new SecurityException("Requires permission "
9167                    + android.Manifest.permission.STOP_APP_SWITCHES);
9168        }
9169
9170        synchronized(this) {
9171            // Note that we don't execute any pending app switches... we will
9172            // let those wait until either the timeout, or the next start
9173            // activity request.
9174            mAppSwitchesAllowedTime = 0;
9175        }
9176    }
9177
9178    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9179            String name) {
9180        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9181            return true;
9182        }
9183
9184        final int perm = checkComponentPermission(
9185                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9186                callingUid, -1, true);
9187        if (perm == PackageManager.PERMISSION_GRANTED) {
9188            return true;
9189        }
9190
9191        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9192        return false;
9193    }
9194
9195    public void setDebugApp(String packageName, boolean waitForDebugger,
9196            boolean persistent) {
9197        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9198                "setDebugApp()");
9199
9200        long ident = Binder.clearCallingIdentity();
9201        try {
9202            // Note that this is not really thread safe if there are multiple
9203            // callers into it at the same time, but that's not a situation we
9204            // care about.
9205            if (persistent) {
9206                final ContentResolver resolver = mContext.getContentResolver();
9207                Settings.Global.putString(
9208                    resolver, Settings.Global.DEBUG_APP,
9209                    packageName);
9210                Settings.Global.putInt(
9211                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9212                    waitForDebugger ? 1 : 0);
9213            }
9214
9215            synchronized (this) {
9216                if (!persistent) {
9217                    mOrigDebugApp = mDebugApp;
9218                    mOrigWaitForDebugger = mWaitForDebugger;
9219                }
9220                mDebugApp = packageName;
9221                mWaitForDebugger = waitForDebugger;
9222                mDebugTransient = !persistent;
9223                if (packageName != null) {
9224                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9225                            false, UserHandle.USER_ALL, "set debug app");
9226                }
9227            }
9228        } finally {
9229            Binder.restoreCallingIdentity(ident);
9230        }
9231    }
9232
9233    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9234        synchronized (this) {
9235            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9236            if (!isDebuggable) {
9237                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9238                    throw new SecurityException("Process not debuggable: " + app.packageName);
9239                }
9240            }
9241
9242            mOpenGlTraceApp = processName;
9243        }
9244    }
9245
9246    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9247            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9248        synchronized (this) {
9249            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9250            if (!isDebuggable) {
9251                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9252                    throw new SecurityException("Process not debuggable: " + app.packageName);
9253                }
9254            }
9255            mProfileApp = processName;
9256            mProfileFile = profileFile;
9257            if (mProfileFd != null) {
9258                try {
9259                    mProfileFd.close();
9260                } catch (IOException e) {
9261                }
9262                mProfileFd = null;
9263            }
9264            mProfileFd = profileFd;
9265            mProfileType = 0;
9266            mAutoStopProfiler = autoStopProfiler;
9267        }
9268    }
9269
9270    @Override
9271    public void setAlwaysFinish(boolean enabled) {
9272        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9273                "setAlwaysFinish()");
9274
9275        Settings.Global.putInt(
9276                mContext.getContentResolver(),
9277                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9278
9279        synchronized (this) {
9280            mAlwaysFinishActivities = enabled;
9281        }
9282    }
9283
9284    @Override
9285    public void setActivityController(IActivityController controller) {
9286        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9287                "setActivityController()");
9288        synchronized (this) {
9289            mController = controller;
9290            Watchdog.getInstance().setActivityController(controller);
9291        }
9292    }
9293
9294    @Override
9295    public void setUserIsMonkey(boolean userIsMonkey) {
9296        synchronized (this) {
9297            synchronized (mPidsSelfLocked) {
9298                final int callingPid = Binder.getCallingPid();
9299                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9300                if (precessRecord == null) {
9301                    throw new SecurityException("Unknown process: " + callingPid);
9302                }
9303                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9304                    throw new SecurityException("Only an instrumentation process "
9305                            + "with a UiAutomation can call setUserIsMonkey");
9306                }
9307            }
9308            mUserIsMonkey = userIsMonkey;
9309        }
9310    }
9311
9312    @Override
9313    public boolean isUserAMonkey() {
9314        synchronized (this) {
9315            // If there is a controller also implies the user is a monkey.
9316            return (mUserIsMonkey || mController != null);
9317        }
9318    }
9319
9320    public void requestBugReport() {
9321        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9322        SystemProperties.set("ctl.start", "bugreport");
9323    }
9324
9325    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9326        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9327    }
9328
9329    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9330        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9331            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9332        }
9333        return KEY_DISPATCHING_TIMEOUT;
9334    }
9335
9336    @Override
9337    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9338        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9339                != PackageManager.PERMISSION_GRANTED) {
9340            throw new SecurityException("Requires permission "
9341                    + android.Manifest.permission.FILTER_EVENTS);
9342        }
9343        ProcessRecord proc;
9344        long timeout;
9345        synchronized (this) {
9346            synchronized (mPidsSelfLocked) {
9347                proc = mPidsSelfLocked.get(pid);
9348            }
9349            timeout = getInputDispatchingTimeoutLocked(proc);
9350        }
9351
9352        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9353            return -1;
9354        }
9355
9356        return timeout;
9357    }
9358
9359    /**
9360     * Handle input dispatching timeouts.
9361     * Returns whether input dispatching should be aborted or not.
9362     */
9363    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9364            final ActivityRecord activity, final ActivityRecord parent,
9365            final boolean aboveSystem, String reason) {
9366        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9367                != PackageManager.PERMISSION_GRANTED) {
9368            throw new SecurityException("Requires permission "
9369                    + android.Manifest.permission.FILTER_EVENTS);
9370        }
9371
9372        final String annotation;
9373        if (reason == null) {
9374            annotation = "Input dispatching timed out";
9375        } else {
9376            annotation = "Input dispatching timed out (" + reason + ")";
9377        }
9378
9379        if (proc != null) {
9380            synchronized (this) {
9381                if (proc.debugging) {
9382                    return false;
9383                }
9384
9385                if (mDidDexOpt) {
9386                    // Give more time since we were dexopting.
9387                    mDidDexOpt = false;
9388                    return false;
9389                }
9390
9391                if (proc.instrumentationClass != null) {
9392                    Bundle info = new Bundle();
9393                    info.putString("shortMsg", "keyDispatchingTimedOut");
9394                    info.putString("longMsg", annotation);
9395                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9396                    return true;
9397                }
9398            }
9399            mHandler.post(new Runnable() {
9400                @Override
9401                public void run() {
9402                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9403                }
9404            });
9405        }
9406
9407        return true;
9408    }
9409
9410    public Bundle getAssistContextExtras(int requestType) {
9411        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9412                "getAssistContextExtras()");
9413        PendingAssistExtras pae;
9414        Bundle extras = new Bundle();
9415        synchronized (this) {
9416            ActivityRecord activity = getFocusedStack().mResumedActivity;
9417            if (activity == null) {
9418                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9419                return null;
9420            }
9421            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9422            if (activity.app == null || activity.app.thread == null) {
9423                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9424                return extras;
9425            }
9426            if (activity.app.pid == Binder.getCallingPid()) {
9427                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9428                return extras;
9429            }
9430            pae = new PendingAssistExtras(activity);
9431            try {
9432                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9433                        requestType);
9434                mPendingAssistExtras.add(pae);
9435                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9436            } catch (RemoteException e) {
9437                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9438                return extras;
9439            }
9440        }
9441        synchronized (pae) {
9442            while (!pae.haveResult) {
9443                try {
9444                    pae.wait();
9445                } catch (InterruptedException e) {
9446                }
9447            }
9448            if (pae.result != null) {
9449                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9450            }
9451        }
9452        synchronized (this) {
9453            mPendingAssistExtras.remove(pae);
9454            mHandler.removeCallbacks(pae);
9455        }
9456        return extras;
9457    }
9458
9459    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9460        PendingAssistExtras pae = (PendingAssistExtras)token;
9461        synchronized (pae) {
9462            pae.result = extras;
9463            pae.haveResult = true;
9464            pae.notifyAll();
9465        }
9466    }
9467
9468    public void registerProcessObserver(IProcessObserver observer) {
9469        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9470                "registerProcessObserver()");
9471        synchronized (this) {
9472            mProcessObservers.register(observer);
9473        }
9474    }
9475
9476    @Override
9477    public void unregisterProcessObserver(IProcessObserver observer) {
9478        synchronized (this) {
9479            mProcessObservers.unregister(observer);
9480        }
9481    }
9482
9483    @Override
9484    public boolean convertFromTranslucent(IBinder token) {
9485        final long origId = Binder.clearCallingIdentity();
9486        try {
9487            synchronized (this) {
9488                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9489                if (r == null) {
9490                    return false;
9491                }
9492                if (r.changeWindowTranslucency(true)) {
9493                    mWindowManager.setAppFullscreen(token, true);
9494                    r.task.stack.releaseMediaResources();
9495                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9496                    return true;
9497                }
9498                return false;
9499            }
9500        } finally {
9501            Binder.restoreCallingIdentity(origId);
9502        }
9503    }
9504
9505    @Override
9506    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9507        final long origId = Binder.clearCallingIdentity();
9508        try {
9509            synchronized (this) {
9510                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9511                if (r == null) {
9512                    return false;
9513                }
9514                if (r.changeWindowTranslucency(false)) {
9515                    r.task.stack.convertToTranslucent(r, options);
9516                    mWindowManager.setAppFullscreen(token, false);
9517                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9518                    return true;
9519                } else {
9520                    r.task.stack.mReturningActivityOptions = options;
9521                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9522                    return false;
9523                }
9524            }
9525        } finally {
9526            Binder.restoreCallingIdentity(origId);
9527        }
9528    }
9529
9530    @Override
9531    public boolean setMediaPlaying(IBinder token, boolean playing) {
9532        final long origId = Binder.clearCallingIdentity();
9533        try {
9534            synchronized (this) {
9535                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9536                if (r != null) {
9537                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9538                }
9539            }
9540            return false;
9541        } finally {
9542            Binder.restoreCallingIdentity(origId);
9543        }
9544    }
9545
9546    @Override
9547    public boolean isBackgroundMediaPlaying(IBinder token) {
9548        final long origId = Binder.clearCallingIdentity();
9549        try {
9550            synchronized (this) {
9551                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9552                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9553                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9554                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9555                return playing;
9556            }
9557        } finally {
9558            Binder.restoreCallingIdentity(origId);
9559        }
9560    }
9561
9562    @Override
9563    public ActivityOptions getActivityOptions(IBinder token) {
9564        final long origId = Binder.clearCallingIdentity();
9565        try {
9566            synchronized (this) {
9567                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9568                if (r != null) {
9569                    final ActivityOptions activityOptions = r.pendingOptions;
9570                    r.pendingOptions = null;
9571                    return activityOptions;
9572                }
9573                return null;
9574            }
9575        } finally {
9576            Binder.restoreCallingIdentity(origId);
9577        }
9578    }
9579
9580    @Override
9581    public void setImmersive(IBinder token, boolean immersive) {
9582        synchronized(this) {
9583            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9584            if (r == null) {
9585                throw new IllegalArgumentException();
9586            }
9587            r.immersive = immersive;
9588
9589            // update associated state if we're frontmost
9590            if (r == mFocusedActivity) {
9591                if (DEBUG_IMMERSIVE) {
9592                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9593                }
9594                applyUpdateLockStateLocked(r);
9595            }
9596        }
9597    }
9598
9599    @Override
9600    public boolean isImmersive(IBinder token) {
9601        synchronized (this) {
9602            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9603            if (r == null) {
9604                throw new IllegalArgumentException();
9605            }
9606            return r.immersive;
9607        }
9608    }
9609
9610    public boolean isTopActivityImmersive() {
9611        enforceNotIsolatedCaller("startActivity");
9612        synchronized (this) {
9613            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9614            return (r != null) ? r.immersive : false;
9615        }
9616    }
9617
9618    @Override
9619    public boolean isTopOfTask(IBinder token) {
9620        synchronized (this) {
9621            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9622            if (r == null) {
9623                throw new IllegalArgumentException();
9624            }
9625            return r.task.getTopActivity() == r;
9626        }
9627    }
9628
9629    public final void enterSafeMode() {
9630        synchronized(this) {
9631            // It only makes sense to do this before the system is ready
9632            // and started launching other packages.
9633            if (!mSystemReady) {
9634                try {
9635                    AppGlobals.getPackageManager().enterSafeMode();
9636                } catch (RemoteException e) {
9637                }
9638            }
9639
9640            mSafeMode = true;
9641        }
9642    }
9643
9644    public final void showSafeModeOverlay() {
9645        View v = LayoutInflater.from(mContext).inflate(
9646                com.android.internal.R.layout.safe_mode, null);
9647        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9648        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9649        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9650        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9651        lp.gravity = Gravity.BOTTOM | Gravity.START;
9652        lp.format = v.getBackground().getOpacity();
9653        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9654                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9655        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9656        ((WindowManager)mContext.getSystemService(
9657                Context.WINDOW_SERVICE)).addView(v, lp);
9658    }
9659
9660    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9661        if (!(sender instanceof PendingIntentRecord)) {
9662            return;
9663        }
9664        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9665        synchronized (stats) {
9666            if (mBatteryStatsService.isOnBattery()) {
9667                mBatteryStatsService.enforceCallingPermission();
9668                PendingIntentRecord rec = (PendingIntentRecord)sender;
9669                int MY_UID = Binder.getCallingUid();
9670                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9671                BatteryStatsImpl.Uid.Pkg pkg =
9672                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9673                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9674                pkg.incWakeupsLocked();
9675            }
9676        }
9677    }
9678
9679    public boolean killPids(int[] pids, String pReason, boolean secure) {
9680        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9681            throw new SecurityException("killPids only available to the system");
9682        }
9683        String reason = (pReason == null) ? "Unknown" : pReason;
9684        // XXX Note: don't acquire main activity lock here, because the window
9685        // manager calls in with its locks held.
9686
9687        boolean killed = false;
9688        synchronized (mPidsSelfLocked) {
9689            int[] types = new int[pids.length];
9690            int worstType = 0;
9691            for (int i=0; i<pids.length; i++) {
9692                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9693                if (proc != null) {
9694                    int type = proc.setAdj;
9695                    types[i] = type;
9696                    if (type > worstType) {
9697                        worstType = type;
9698                    }
9699                }
9700            }
9701
9702            // If the worst oom_adj is somewhere in the cached proc LRU range,
9703            // then constrain it so we will kill all cached procs.
9704            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9705                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9706                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9707            }
9708
9709            // If this is not a secure call, don't let it kill processes that
9710            // are important.
9711            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9712                worstType = ProcessList.SERVICE_ADJ;
9713            }
9714
9715            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9716            for (int i=0; i<pids.length; i++) {
9717                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9718                if (proc == null) {
9719                    continue;
9720                }
9721                int adj = proc.setAdj;
9722                if (adj >= worstType && !proc.killedByAm) {
9723                    killUnneededProcessLocked(proc, reason);
9724                    killed = true;
9725                }
9726            }
9727        }
9728        return killed;
9729    }
9730
9731    @Override
9732    public void killUid(int uid, String reason) {
9733        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9734            throw new SecurityException("killUid only available to the system");
9735        }
9736        synchronized (this) {
9737            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9738                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9739                    reason != null ? reason : "kill uid");
9740        }
9741    }
9742
9743    @Override
9744    public boolean killProcessesBelowForeground(String reason) {
9745        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9746            throw new SecurityException("killProcessesBelowForeground() only available to system");
9747        }
9748
9749        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9750    }
9751
9752    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9753        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9754            throw new SecurityException("killProcessesBelowAdj() only available to system");
9755        }
9756
9757        boolean killed = false;
9758        synchronized (mPidsSelfLocked) {
9759            final int size = mPidsSelfLocked.size();
9760            for (int i = 0; i < size; i++) {
9761                final int pid = mPidsSelfLocked.keyAt(i);
9762                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9763                if (proc == null) continue;
9764
9765                final int adj = proc.setAdj;
9766                if (adj > belowAdj && !proc.killedByAm) {
9767                    killUnneededProcessLocked(proc, reason);
9768                    killed = true;
9769                }
9770            }
9771        }
9772        return killed;
9773    }
9774
9775    @Override
9776    public void hang(final IBinder who, boolean allowRestart) {
9777        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9778                != PackageManager.PERMISSION_GRANTED) {
9779            throw new SecurityException("Requires permission "
9780                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9781        }
9782
9783        final IBinder.DeathRecipient death = new DeathRecipient() {
9784            @Override
9785            public void binderDied() {
9786                synchronized (this) {
9787                    notifyAll();
9788                }
9789            }
9790        };
9791
9792        try {
9793            who.linkToDeath(death, 0);
9794        } catch (RemoteException e) {
9795            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9796            return;
9797        }
9798
9799        synchronized (this) {
9800            Watchdog.getInstance().setAllowRestart(allowRestart);
9801            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9802            synchronized (death) {
9803                while (who.isBinderAlive()) {
9804                    try {
9805                        death.wait();
9806                    } catch (InterruptedException e) {
9807                    }
9808                }
9809            }
9810            Watchdog.getInstance().setAllowRestart(true);
9811        }
9812    }
9813
9814    @Override
9815    public void restart() {
9816        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9817                != PackageManager.PERMISSION_GRANTED) {
9818            throw new SecurityException("Requires permission "
9819                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9820        }
9821
9822        Log.i(TAG, "Sending shutdown broadcast...");
9823
9824        BroadcastReceiver br = new BroadcastReceiver() {
9825            @Override public void onReceive(Context context, Intent intent) {
9826                // Now the broadcast is done, finish up the low-level shutdown.
9827                Log.i(TAG, "Shutting down activity manager...");
9828                shutdown(10000);
9829                Log.i(TAG, "Shutdown complete, restarting!");
9830                Process.killProcess(Process.myPid());
9831                System.exit(10);
9832            }
9833        };
9834
9835        // First send the high-level shut down broadcast.
9836        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9837        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9838        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9839        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9840        mContext.sendOrderedBroadcastAsUser(intent,
9841                UserHandle.ALL, null, br, mHandler, 0, null, null);
9842        */
9843        br.onReceive(mContext, intent);
9844    }
9845
9846    private long getLowRamTimeSinceIdle(long now) {
9847        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9848    }
9849
9850    @Override
9851    public void performIdleMaintenance() {
9852        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9853                != PackageManager.PERMISSION_GRANTED) {
9854            throw new SecurityException("Requires permission "
9855                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9856        }
9857
9858        synchronized (this) {
9859            final long now = SystemClock.uptimeMillis();
9860            final long timeSinceLastIdle = now - mLastIdleTime;
9861            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9862            mLastIdleTime = now;
9863            mLowRamTimeSinceLastIdle = 0;
9864            if (mLowRamStartTime != 0) {
9865                mLowRamStartTime = now;
9866            }
9867
9868            StringBuilder sb = new StringBuilder(128);
9869            sb.append("Idle maintenance over ");
9870            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9871            sb.append(" low RAM for ");
9872            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9873            Slog.i(TAG, sb.toString());
9874
9875            // If at least 1/3 of our time since the last idle period has been spent
9876            // with RAM low, then we want to kill processes.
9877            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9878
9879            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9880                ProcessRecord proc = mLruProcesses.get(i);
9881                if (proc.notCachedSinceIdle) {
9882                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9883                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9884                        if (doKilling && proc.initialIdlePss != 0
9885                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9886                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9887                                    + " from " + proc.initialIdlePss + ")");
9888                        }
9889                    }
9890                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9891                    proc.notCachedSinceIdle = true;
9892                    proc.initialIdlePss = 0;
9893                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9894                            isSleeping(), now);
9895                }
9896            }
9897
9898            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9899            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9900        }
9901    }
9902
9903    private void retrieveSettings() {
9904        final ContentResolver resolver = mContext.getContentResolver();
9905        String debugApp = Settings.Global.getString(
9906            resolver, Settings.Global.DEBUG_APP);
9907        boolean waitForDebugger = Settings.Global.getInt(
9908            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9909        boolean alwaysFinishActivities = Settings.Global.getInt(
9910            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9911        boolean forceRtl = Settings.Global.getInt(
9912                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9913        // Transfer any global setting for forcing RTL layout, into a System Property
9914        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9915
9916        Configuration configuration = new Configuration();
9917        Settings.System.getConfiguration(resolver, configuration);
9918        if (forceRtl) {
9919            // This will take care of setting the correct layout direction flags
9920            configuration.setLayoutDirection(configuration.locale);
9921        }
9922
9923        synchronized (this) {
9924            mDebugApp = mOrigDebugApp = debugApp;
9925            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9926            mAlwaysFinishActivities = alwaysFinishActivities;
9927            // This happens before any activities are started, so we can
9928            // change mConfiguration in-place.
9929            updateConfigurationLocked(configuration, null, false, true);
9930            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9931        }
9932    }
9933
9934    public boolean testIsSystemReady() {
9935        // no need to synchronize(this) just to read & return the value
9936        return mSystemReady;
9937    }
9938
9939    private static File getCalledPreBootReceiversFile() {
9940        File dataDir = Environment.getDataDirectory();
9941        File systemDir = new File(dataDir, "system");
9942        File fname = new File(systemDir, "called_pre_boots.dat");
9943        return fname;
9944    }
9945
9946    static final int LAST_DONE_VERSION = 10000;
9947
9948    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9949        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9950        File file = getCalledPreBootReceiversFile();
9951        FileInputStream fis = null;
9952        try {
9953            fis = new FileInputStream(file);
9954            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9955            int fvers = dis.readInt();
9956            if (fvers == LAST_DONE_VERSION) {
9957                String vers = dis.readUTF();
9958                String codename = dis.readUTF();
9959                String build = dis.readUTF();
9960                if (android.os.Build.VERSION.RELEASE.equals(vers)
9961                        && android.os.Build.VERSION.CODENAME.equals(codename)
9962                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9963                    int num = dis.readInt();
9964                    while (num > 0) {
9965                        num--;
9966                        String pkg = dis.readUTF();
9967                        String cls = dis.readUTF();
9968                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9969                    }
9970                }
9971            }
9972        } catch (FileNotFoundException e) {
9973        } catch (IOException e) {
9974            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9975        } finally {
9976            if (fis != null) {
9977                try {
9978                    fis.close();
9979                } catch (IOException e) {
9980                }
9981            }
9982        }
9983        return lastDoneReceivers;
9984    }
9985
9986    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9987        File file = getCalledPreBootReceiversFile();
9988        FileOutputStream fos = null;
9989        DataOutputStream dos = null;
9990        try {
9991            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9992            fos = new FileOutputStream(file);
9993            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9994            dos.writeInt(LAST_DONE_VERSION);
9995            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9996            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9997            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9998            dos.writeInt(list.size());
9999            for (int i=0; i<list.size(); i++) {
10000                dos.writeUTF(list.get(i).getPackageName());
10001                dos.writeUTF(list.get(i).getClassName());
10002            }
10003        } catch (IOException e) {
10004            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10005            file.delete();
10006        } finally {
10007            FileUtils.sync(fos);
10008            if (dos != null) {
10009                try {
10010                    dos.close();
10011                } catch (IOException e) {
10012                    // TODO Auto-generated catch block
10013                    e.printStackTrace();
10014                }
10015            }
10016        }
10017    }
10018
10019    public void systemReady(final Runnable goingCallback) {
10020        synchronized(this) {
10021            if (mSystemReady) {
10022                if (goingCallback != null) goingCallback.run();
10023                return;
10024            }
10025
10026            // Make sure we have the current profile info, since it is needed for
10027            // security checks.
10028            updateCurrentProfileIdsLocked();
10029
10030            if (mRecentTasks == null) {
10031                mRecentTasks = mTaskPersister.restoreTasksLocked();
10032                if (!mRecentTasks.isEmpty()) {
10033                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10034                }
10035                mTaskPersister.startPersisting();
10036            }
10037
10038            // Check to see if there are any update receivers to run.
10039            if (!mDidUpdate) {
10040                if (mWaitingUpdate) {
10041                    return;
10042                }
10043                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10044                List<ResolveInfo> ris = null;
10045                try {
10046                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
10047                            intent, null, 0, 0);
10048                } catch (RemoteException e) {
10049                }
10050                if (ris != null) {
10051                    for (int i=ris.size()-1; i>=0; i--) {
10052                        if ((ris.get(i).activityInfo.applicationInfo.flags
10053                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
10054                            ris.remove(i);
10055                        }
10056                    }
10057                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10058
10059                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10060
10061                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10062                    for (int i=0; i<ris.size(); i++) {
10063                        ActivityInfo ai = ris.get(i).activityInfo;
10064                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10065                        if (lastDoneReceivers.contains(comp)) {
10066                            // We already did the pre boot receiver for this app with the current
10067                            // platform version, so don't do it again...
10068                            ris.remove(i);
10069                            i--;
10070                            // ...however, do keep it as one that has been done, so we don't
10071                            // forget about it when rewriting the file of last done receivers.
10072                            doneReceivers.add(comp);
10073                        }
10074                    }
10075
10076                    final int[] users = getUsersLocked();
10077                    for (int i=0; i<ris.size(); i++) {
10078                        ActivityInfo ai = ris.get(i).activityInfo;
10079                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10080                        doneReceivers.add(comp);
10081                        intent.setComponent(comp);
10082                        for (int j=0; j<users.length; j++) {
10083                            IIntentReceiver finisher = null;
10084                            if (i == ris.size()-1 && j == users.length-1) {
10085                                finisher = new IIntentReceiver.Stub() {
10086                                    public void performReceive(Intent intent, int resultCode,
10087                                            String data, Bundle extras, boolean ordered,
10088                                            boolean sticky, int sendingUser) {
10089                                        // The raw IIntentReceiver interface is called
10090                                        // with the AM lock held, so redispatch to
10091                                        // execute our code without the lock.
10092                                        mHandler.post(new Runnable() {
10093                                            public void run() {
10094                                                synchronized (ActivityManagerService.this) {
10095                                                    mDidUpdate = true;
10096                                                }
10097                                                writeLastDonePreBootReceivers(doneReceivers);
10098                                                showBootMessage(mContext.getText(
10099                                                        R.string.android_upgrading_complete),
10100                                                        false);
10101                                                systemReady(goingCallback);
10102                                            }
10103                                        });
10104                                    }
10105                                };
10106                            }
10107                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
10108                                    + " for user " + users[j]);
10109                            broadcastIntentLocked(null, null, intent, null, finisher,
10110                                    0, null, null, null, AppOpsManager.OP_NONE,
10111                                    true, false, MY_PID, Process.SYSTEM_UID,
10112                                    users[j]);
10113                            if (finisher != null) {
10114                                mWaitingUpdate = true;
10115                            }
10116                        }
10117                    }
10118                }
10119                if (mWaitingUpdate) {
10120                    return;
10121                }
10122                mDidUpdate = true;
10123            }
10124
10125            mAppOpsService.systemReady();
10126            mSystemReady = true;
10127        }
10128
10129        ArrayList<ProcessRecord> procsToKill = null;
10130        synchronized(mPidsSelfLocked) {
10131            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10132                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10133                if (!isAllowedWhileBooting(proc.info)){
10134                    if (procsToKill == null) {
10135                        procsToKill = new ArrayList<ProcessRecord>();
10136                    }
10137                    procsToKill.add(proc);
10138                }
10139            }
10140        }
10141
10142        synchronized(this) {
10143            if (procsToKill != null) {
10144                for (int i=procsToKill.size()-1; i>=0; i--) {
10145                    ProcessRecord proc = procsToKill.get(i);
10146                    Slog.i(TAG, "Removing system update proc: " + proc);
10147                    removeProcessLocked(proc, true, false, "system update done");
10148                }
10149            }
10150
10151            // Now that we have cleaned up any update processes, we
10152            // are ready to start launching real processes and know that
10153            // we won't trample on them any more.
10154            mProcessesReady = true;
10155        }
10156
10157        Slog.i(TAG, "System now ready");
10158        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10159            SystemClock.uptimeMillis());
10160
10161        synchronized(this) {
10162            // Make sure we have no pre-ready processes sitting around.
10163
10164            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10165                ResolveInfo ri = mContext.getPackageManager()
10166                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10167                                STOCK_PM_FLAGS);
10168                CharSequence errorMsg = null;
10169                if (ri != null) {
10170                    ActivityInfo ai = ri.activityInfo;
10171                    ApplicationInfo app = ai.applicationInfo;
10172                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10173                        mTopAction = Intent.ACTION_FACTORY_TEST;
10174                        mTopData = null;
10175                        mTopComponent = new ComponentName(app.packageName,
10176                                ai.name);
10177                    } else {
10178                        errorMsg = mContext.getResources().getText(
10179                                com.android.internal.R.string.factorytest_not_system);
10180                    }
10181                } else {
10182                    errorMsg = mContext.getResources().getText(
10183                            com.android.internal.R.string.factorytest_no_action);
10184                }
10185                if (errorMsg != null) {
10186                    mTopAction = null;
10187                    mTopData = null;
10188                    mTopComponent = null;
10189                    Message msg = Message.obtain();
10190                    msg.what = SHOW_FACTORY_ERROR_MSG;
10191                    msg.getData().putCharSequence("msg", errorMsg);
10192                    mHandler.sendMessage(msg);
10193                }
10194            }
10195        }
10196
10197        retrieveSettings();
10198
10199        synchronized (this) {
10200            readGrantedUriPermissionsLocked();
10201        }
10202
10203        if (goingCallback != null) goingCallback.run();
10204
10205        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10206                Integer.toString(mCurrentUserId), mCurrentUserId);
10207        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10208                Integer.toString(mCurrentUserId), mCurrentUserId);
10209        mSystemServiceManager.startUser(mCurrentUserId);
10210
10211        synchronized (this) {
10212            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10213                try {
10214                    List apps = AppGlobals.getPackageManager().
10215                        getPersistentApplications(STOCK_PM_FLAGS);
10216                    if (apps != null) {
10217                        int N = apps.size();
10218                        int i;
10219                        for (i=0; i<N; i++) {
10220                            ApplicationInfo info
10221                                = (ApplicationInfo)apps.get(i);
10222                            if (info != null &&
10223                                    !info.packageName.equals("android")) {
10224                                addAppLocked(info, false, null /* ABI override */);
10225                            }
10226                        }
10227                    }
10228                } catch (RemoteException ex) {
10229                    // pm is in same process, this will never happen.
10230                }
10231            }
10232
10233            // Start up initial activity.
10234            mBooting = true;
10235
10236            try {
10237                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10238                    Message msg = Message.obtain();
10239                    msg.what = SHOW_UID_ERROR_MSG;
10240                    mHandler.sendMessage(msg);
10241                }
10242            } catch (RemoteException e) {
10243            }
10244
10245            long ident = Binder.clearCallingIdentity();
10246            try {
10247                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10248                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10249                        | Intent.FLAG_RECEIVER_FOREGROUND);
10250                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10251                broadcastIntentLocked(null, null, intent,
10252                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10253                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10254                intent = new Intent(Intent.ACTION_USER_STARTING);
10255                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10256                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10257                broadcastIntentLocked(null, null, intent,
10258                        null, new IIntentReceiver.Stub() {
10259                            @Override
10260                            public void performReceive(Intent intent, int resultCode, String data,
10261                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10262                                    throws RemoteException {
10263                            }
10264                        }, 0, null, null,
10265                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10266                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10267            } catch (Throwable t) {
10268                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10269            } finally {
10270                Binder.restoreCallingIdentity(ident);
10271            }
10272            mStackSupervisor.resumeTopActivitiesLocked();
10273            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10274        }
10275    }
10276
10277    private boolean makeAppCrashingLocked(ProcessRecord app,
10278            String shortMsg, String longMsg, String stackTrace) {
10279        app.crashing = true;
10280        app.crashingReport = generateProcessError(app,
10281                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10282        startAppProblemLocked(app);
10283        app.stopFreezingAllLocked();
10284        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10285    }
10286
10287    private void makeAppNotRespondingLocked(ProcessRecord app,
10288            String activity, String shortMsg, String longMsg) {
10289        app.notResponding = true;
10290        app.notRespondingReport = generateProcessError(app,
10291                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10292                activity, shortMsg, longMsg, null);
10293        startAppProblemLocked(app);
10294        app.stopFreezingAllLocked();
10295    }
10296
10297    /**
10298     * Generate a process error record, suitable for attachment to a ProcessRecord.
10299     *
10300     * @param app The ProcessRecord in which the error occurred.
10301     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10302     *                      ActivityManager.AppErrorStateInfo
10303     * @param activity The activity associated with the crash, if known.
10304     * @param shortMsg Short message describing the crash.
10305     * @param longMsg Long message describing the crash.
10306     * @param stackTrace Full crash stack trace, may be null.
10307     *
10308     * @return Returns a fully-formed AppErrorStateInfo record.
10309     */
10310    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10311            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10312        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10313
10314        report.condition = condition;
10315        report.processName = app.processName;
10316        report.pid = app.pid;
10317        report.uid = app.info.uid;
10318        report.tag = activity;
10319        report.shortMsg = shortMsg;
10320        report.longMsg = longMsg;
10321        report.stackTrace = stackTrace;
10322
10323        return report;
10324    }
10325
10326    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10327        synchronized (this) {
10328            app.crashing = false;
10329            app.crashingReport = null;
10330            app.notResponding = false;
10331            app.notRespondingReport = null;
10332            if (app.anrDialog == fromDialog) {
10333                app.anrDialog = null;
10334            }
10335            if (app.waitDialog == fromDialog) {
10336                app.waitDialog = null;
10337            }
10338            if (app.pid > 0 && app.pid != MY_PID) {
10339                handleAppCrashLocked(app, null, null, null);
10340                killUnneededProcessLocked(app, "user request after error");
10341            }
10342        }
10343    }
10344
10345    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10346            String stackTrace) {
10347        long now = SystemClock.uptimeMillis();
10348
10349        Long crashTime;
10350        if (!app.isolated) {
10351            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10352        } else {
10353            crashTime = null;
10354        }
10355        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10356            // This process loses!
10357            Slog.w(TAG, "Process " + app.info.processName
10358                    + " has crashed too many times: killing!");
10359            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10360                    app.userId, app.info.processName, app.uid);
10361            mStackSupervisor.handleAppCrashLocked(app);
10362            if (!app.persistent) {
10363                // We don't want to start this process again until the user
10364                // explicitly does so...  but for persistent process, we really
10365                // need to keep it running.  If a persistent process is actually
10366                // repeatedly crashing, then badness for everyone.
10367                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10368                        app.info.processName);
10369                if (!app.isolated) {
10370                    // XXX We don't have a way to mark isolated processes
10371                    // as bad, since they don't have a peristent identity.
10372                    mBadProcesses.put(app.info.processName, app.uid,
10373                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10374                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10375                }
10376                app.bad = true;
10377                app.removed = true;
10378                // Don't let services in this process be restarted and potentially
10379                // annoy the user repeatedly.  Unless it is persistent, since those
10380                // processes run critical code.
10381                removeProcessLocked(app, false, false, "crash");
10382                mStackSupervisor.resumeTopActivitiesLocked();
10383                return false;
10384            }
10385            mStackSupervisor.resumeTopActivitiesLocked();
10386        } else {
10387            mStackSupervisor.finishTopRunningActivityLocked(app);
10388        }
10389
10390        // Bump up the crash count of any services currently running in the proc.
10391        for (int i=app.services.size()-1; i>=0; i--) {
10392            // Any services running in the application need to be placed
10393            // back in the pending list.
10394            ServiceRecord sr = app.services.valueAt(i);
10395            sr.crashCount++;
10396        }
10397
10398        // If the crashing process is what we consider to be the "home process" and it has been
10399        // replaced by a third-party app, clear the package preferred activities from packages
10400        // with a home activity running in the process to prevent a repeatedly crashing app
10401        // from blocking the user to manually clear the list.
10402        final ArrayList<ActivityRecord> activities = app.activities;
10403        if (app == mHomeProcess && activities.size() > 0
10404                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10405            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10406                final ActivityRecord r = activities.get(activityNdx);
10407                if (r.isHomeActivity()) {
10408                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10409                    try {
10410                        ActivityThread.getPackageManager()
10411                                .clearPackagePreferredActivities(r.packageName);
10412                    } catch (RemoteException c) {
10413                        // pm is in same process, this will never happen.
10414                    }
10415                }
10416            }
10417        }
10418
10419        if (!app.isolated) {
10420            // XXX Can't keep track of crash times for isolated processes,
10421            // because they don't have a perisistent identity.
10422            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10423        }
10424
10425        return true;
10426    }
10427
10428    void startAppProblemLocked(ProcessRecord app) {
10429        if (app.userId == mCurrentUserId) {
10430            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10431                    mContext, app.info.packageName, app.info.flags);
10432        } else {
10433            // If this app is not running under the current user, then we
10434            // can't give it a report button because that would require
10435            // launching the report UI under a different user.
10436            app.errorReportReceiver = null;
10437        }
10438        skipCurrentReceiverLocked(app);
10439    }
10440
10441    void skipCurrentReceiverLocked(ProcessRecord app) {
10442        for (BroadcastQueue queue : mBroadcastQueues) {
10443            queue.skipCurrentReceiverLocked(app);
10444        }
10445    }
10446
10447    /**
10448     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10449     * The application process will exit immediately after this call returns.
10450     * @param app object of the crashing app, null for the system server
10451     * @param crashInfo describing the exception
10452     */
10453    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10454        ProcessRecord r = findAppProcess(app, "Crash");
10455        final String processName = app == null ? "system_server"
10456                : (r == null ? "unknown" : r.processName);
10457
10458        handleApplicationCrashInner("crash", r, processName, crashInfo);
10459    }
10460
10461    /* Native crash reporting uses this inner version because it needs to be somewhat
10462     * decoupled from the AM-managed cleanup lifecycle
10463     */
10464    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10465            ApplicationErrorReport.CrashInfo crashInfo) {
10466        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10467                UserHandle.getUserId(Binder.getCallingUid()), processName,
10468                r == null ? -1 : r.info.flags,
10469                crashInfo.exceptionClassName,
10470                crashInfo.exceptionMessage,
10471                crashInfo.throwFileName,
10472                crashInfo.throwLineNumber);
10473
10474        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10475
10476        crashApplication(r, crashInfo);
10477    }
10478
10479    public void handleApplicationStrictModeViolation(
10480            IBinder app,
10481            int violationMask,
10482            StrictMode.ViolationInfo info) {
10483        ProcessRecord r = findAppProcess(app, "StrictMode");
10484        if (r == null) {
10485            return;
10486        }
10487
10488        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10489            Integer stackFingerprint = info.hashCode();
10490            boolean logIt = true;
10491            synchronized (mAlreadyLoggedViolatedStacks) {
10492                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10493                    logIt = false;
10494                    // TODO: sub-sample into EventLog for these, with
10495                    // the info.durationMillis?  Then we'd get
10496                    // the relative pain numbers, without logging all
10497                    // the stack traces repeatedly.  We'd want to do
10498                    // likewise in the client code, which also does
10499                    // dup suppression, before the Binder call.
10500                } else {
10501                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10502                        mAlreadyLoggedViolatedStacks.clear();
10503                    }
10504                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10505                }
10506            }
10507            if (logIt) {
10508                logStrictModeViolationToDropBox(r, info);
10509            }
10510        }
10511
10512        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10513            AppErrorResult result = new AppErrorResult();
10514            synchronized (this) {
10515                final long origId = Binder.clearCallingIdentity();
10516
10517                Message msg = Message.obtain();
10518                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10519                HashMap<String, Object> data = new HashMap<String, Object>();
10520                data.put("result", result);
10521                data.put("app", r);
10522                data.put("violationMask", violationMask);
10523                data.put("info", info);
10524                msg.obj = data;
10525                mHandler.sendMessage(msg);
10526
10527                Binder.restoreCallingIdentity(origId);
10528            }
10529            int res = result.get();
10530            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10531        }
10532    }
10533
10534    // Depending on the policy in effect, there could be a bunch of
10535    // these in quick succession so we try to batch these together to
10536    // minimize disk writes, number of dropbox entries, and maximize
10537    // compression, by having more fewer, larger records.
10538    private void logStrictModeViolationToDropBox(
10539            ProcessRecord process,
10540            StrictMode.ViolationInfo info) {
10541        if (info == null) {
10542            return;
10543        }
10544        final boolean isSystemApp = process == null ||
10545                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10546                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10547        final String processName = process == null ? "unknown" : process.processName;
10548        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10549        final DropBoxManager dbox = (DropBoxManager)
10550                mContext.getSystemService(Context.DROPBOX_SERVICE);
10551
10552        // Exit early if the dropbox isn't configured to accept this report type.
10553        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10554
10555        boolean bufferWasEmpty;
10556        boolean needsFlush;
10557        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10558        synchronized (sb) {
10559            bufferWasEmpty = sb.length() == 0;
10560            appendDropBoxProcessHeaders(process, processName, sb);
10561            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10562            sb.append("System-App: ").append(isSystemApp).append("\n");
10563            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10564            if (info.violationNumThisLoop != 0) {
10565                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10566            }
10567            if (info.numAnimationsRunning != 0) {
10568                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10569            }
10570            if (info.broadcastIntentAction != null) {
10571                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10572            }
10573            if (info.durationMillis != -1) {
10574                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10575            }
10576            if (info.numInstances != -1) {
10577                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10578            }
10579            if (info.tags != null) {
10580                for (String tag : info.tags) {
10581                    sb.append("Span-Tag: ").append(tag).append("\n");
10582                }
10583            }
10584            sb.append("\n");
10585            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10586                sb.append(info.crashInfo.stackTrace);
10587            }
10588            sb.append("\n");
10589
10590            // Only buffer up to ~64k.  Various logging bits truncate
10591            // things at 128k.
10592            needsFlush = (sb.length() > 64 * 1024);
10593        }
10594
10595        // Flush immediately if the buffer's grown too large, or this
10596        // is a non-system app.  Non-system apps are isolated with a
10597        // different tag & policy and not batched.
10598        //
10599        // Batching is useful during internal testing with
10600        // StrictMode settings turned up high.  Without batching,
10601        // thousands of separate files could be created on boot.
10602        if (!isSystemApp || needsFlush) {
10603            new Thread("Error dump: " + dropboxTag) {
10604                @Override
10605                public void run() {
10606                    String report;
10607                    synchronized (sb) {
10608                        report = sb.toString();
10609                        sb.delete(0, sb.length());
10610                        sb.trimToSize();
10611                    }
10612                    if (report.length() != 0) {
10613                        dbox.addText(dropboxTag, report);
10614                    }
10615                }
10616            }.start();
10617            return;
10618        }
10619
10620        // System app batching:
10621        if (!bufferWasEmpty) {
10622            // An existing dropbox-writing thread is outstanding, so
10623            // we don't need to start it up.  The existing thread will
10624            // catch the buffer appends we just did.
10625            return;
10626        }
10627
10628        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10629        // (After this point, we shouldn't access AMS internal data structures.)
10630        new Thread("Error dump: " + dropboxTag) {
10631            @Override
10632            public void run() {
10633                // 5 second sleep to let stacks arrive and be batched together
10634                try {
10635                    Thread.sleep(5000);  // 5 seconds
10636                } catch (InterruptedException e) {}
10637
10638                String errorReport;
10639                synchronized (mStrictModeBuffer) {
10640                    errorReport = mStrictModeBuffer.toString();
10641                    if (errorReport.length() == 0) {
10642                        return;
10643                    }
10644                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10645                    mStrictModeBuffer.trimToSize();
10646                }
10647                dbox.addText(dropboxTag, errorReport);
10648            }
10649        }.start();
10650    }
10651
10652    /**
10653     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10654     * @param app object of the crashing app, null for the system server
10655     * @param tag reported by the caller
10656     * @param crashInfo describing the context of the error
10657     * @return true if the process should exit immediately (WTF is fatal)
10658     */
10659    public boolean handleApplicationWtf(IBinder app, String tag,
10660            ApplicationErrorReport.CrashInfo crashInfo) {
10661        ProcessRecord r = findAppProcess(app, "WTF");
10662        final String processName = app == null ? "system_server"
10663                : (r == null ? "unknown" : r.processName);
10664
10665        EventLog.writeEvent(EventLogTags.AM_WTF,
10666                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10667                processName,
10668                r == null ? -1 : r.info.flags,
10669                tag, crashInfo.exceptionMessage);
10670
10671        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10672
10673        if (r != null && r.pid != Process.myPid() &&
10674                Settings.Global.getInt(mContext.getContentResolver(),
10675                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10676            crashApplication(r, crashInfo);
10677            return true;
10678        } else {
10679            return false;
10680        }
10681    }
10682
10683    /**
10684     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10685     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10686     */
10687    private ProcessRecord findAppProcess(IBinder app, String reason) {
10688        if (app == null) {
10689            return null;
10690        }
10691
10692        synchronized (this) {
10693            final int NP = mProcessNames.getMap().size();
10694            for (int ip=0; ip<NP; ip++) {
10695                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10696                final int NA = apps.size();
10697                for (int ia=0; ia<NA; ia++) {
10698                    ProcessRecord p = apps.valueAt(ia);
10699                    if (p.thread != null && p.thread.asBinder() == app) {
10700                        return p;
10701                    }
10702                }
10703            }
10704
10705            Slog.w(TAG, "Can't find mystery application for " + reason
10706                    + " from pid=" + Binder.getCallingPid()
10707                    + " uid=" + Binder.getCallingUid() + ": " + app);
10708            return null;
10709        }
10710    }
10711
10712    /**
10713     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10714     * to append various headers to the dropbox log text.
10715     */
10716    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10717            StringBuilder sb) {
10718        // Watchdog thread ends up invoking this function (with
10719        // a null ProcessRecord) to add the stack file to dropbox.
10720        // Do not acquire a lock on this (am) in such cases, as it
10721        // could cause a potential deadlock, if and when watchdog
10722        // is invoked due to unavailability of lock on am and it
10723        // would prevent watchdog from killing system_server.
10724        if (process == null) {
10725            sb.append("Process: ").append(processName).append("\n");
10726            return;
10727        }
10728        // Note: ProcessRecord 'process' is guarded by the service
10729        // instance.  (notably process.pkgList, which could otherwise change
10730        // concurrently during execution of this method)
10731        synchronized (this) {
10732            sb.append("Process: ").append(processName).append("\n");
10733            int flags = process.info.flags;
10734            IPackageManager pm = AppGlobals.getPackageManager();
10735            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10736            for (int ip=0; ip<process.pkgList.size(); ip++) {
10737                String pkg = process.pkgList.keyAt(ip);
10738                sb.append("Package: ").append(pkg);
10739                try {
10740                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10741                    if (pi != null) {
10742                        sb.append(" v").append(pi.versionCode);
10743                        if (pi.versionName != null) {
10744                            sb.append(" (").append(pi.versionName).append(")");
10745                        }
10746                    }
10747                } catch (RemoteException e) {
10748                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10749                }
10750                sb.append("\n");
10751            }
10752        }
10753    }
10754
10755    private static String processClass(ProcessRecord process) {
10756        if (process == null || process.pid == MY_PID) {
10757            return "system_server";
10758        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10759            return "system_app";
10760        } else {
10761            return "data_app";
10762        }
10763    }
10764
10765    /**
10766     * Write a description of an error (crash, WTF, ANR) to the drop box.
10767     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10768     * @param process which caused the error, null means the system server
10769     * @param activity which triggered the error, null if unknown
10770     * @param parent activity related to the error, null if unknown
10771     * @param subject line related to the error, null if absent
10772     * @param report in long form describing the error, null if absent
10773     * @param logFile to include in the report, null if none
10774     * @param crashInfo giving an application stack trace, null if absent
10775     */
10776    public void addErrorToDropBox(String eventType,
10777            ProcessRecord process, String processName, ActivityRecord activity,
10778            ActivityRecord parent, String subject,
10779            final String report, final File logFile,
10780            final ApplicationErrorReport.CrashInfo crashInfo) {
10781        // NOTE -- this must never acquire the ActivityManagerService lock,
10782        // otherwise the watchdog may be prevented from resetting the system.
10783
10784        final String dropboxTag = processClass(process) + "_" + eventType;
10785        final DropBoxManager dbox = (DropBoxManager)
10786                mContext.getSystemService(Context.DROPBOX_SERVICE);
10787
10788        // Exit early if the dropbox isn't configured to accept this report type.
10789        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10790
10791        final StringBuilder sb = new StringBuilder(1024);
10792        appendDropBoxProcessHeaders(process, processName, sb);
10793        if (activity != null) {
10794            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10795        }
10796        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10797            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10798        }
10799        if (parent != null && parent != activity) {
10800            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10801        }
10802        if (subject != null) {
10803            sb.append("Subject: ").append(subject).append("\n");
10804        }
10805        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10806        if (Debug.isDebuggerConnected()) {
10807            sb.append("Debugger: Connected\n");
10808        }
10809        sb.append("\n");
10810
10811        // Do the rest in a worker thread to avoid blocking the caller on I/O
10812        // (After this point, we shouldn't access AMS internal data structures.)
10813        Thread worker = new Thread("Error dump: " + dropboxTag) {
10814            @Override
10815            public void run() {
10816                if (report != null) {
10817                    sb.append(report);
10818                }
10819                if (logFile != null) {
10820                    try {
10821                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10822                                    "\n\n[[TRUNCATED]]"));
10823                    } catch (IOException e) {
10824                        Slog.e(TAG, "Error reading " + logFile, e);
10825                    }
10826                }
10827                if (crashInfo != null && crashInfo.stackTrace != null) {
10828                    sb.append(crashInfo.stackTrace);
10829                }
10830
10831                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10832                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10833                if (lines > 0) {
10834                    sb.append("\n");
10835
10836                    // Merge several logcat streams, and take the last N lines
10837                    InputStreamReader input = null;
10838                    try {
10839                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10840                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10841                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10842
10843                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10844                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10845                        input = new InputStreamReader(logcat.getInputStream());
10846
10847                        int num;
10848                        char[] buf = new char[8192];
10849                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10850                    } catch (IOException e) {
10851                        Slog.e(TAG, "Error running logcat", e);
10852                    } finally {
10853                        if (input != null) try { input.close(); } catch (IOException e) {}
10854                    }
10855                }
10856
10857                dbox.addText(dropboxTag, sb.toString());
10858            }
10859        };
10860
10861        if (process == null) {
10862            // If process is null, we are being called from some internal code
10863            // and may be about to die -- run this synchronously.
10864            worker.run();
10865        } else {
10866            worker.start();
10867        }
10868    }
10869
10870    /**
10871     * Bring up the "unexpected error" dialog box for a crashing app.
10872     * Deal with edge cases (intercepts from instrumented applications,
10873     * ActivityController, error intent receivers, that sort of thing).
10874     * @param r the application crashing
10875     * @param crashInfo describing the failure
10876     */
10877    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10878        long timeMillis = System.currentTimeMillis();
10879        String shortMsg = crashInfo.exceptionClassName;
10880        String longMsg = crashInfo.exceptionMessage;
10881        String stackTrace = crashInfo.stackTrace;
10882        if (shortMsg != null && longMsg != null) {
10883            longMsg = shortMsg + ": " + longMsg;
10884        } else if (shortMsg != null) {
10885            longMsg = shortMsg;
10886        }
10887
10888        AppErrorResult result = new AppErrorResult();
10889        synchronized (this) {
10890            if (mController != null) {
10891                try {
10892                    String name = r != null ? r.processName : null;
10893                    int pid = r != null ? r.pid : Binder.getCallingPid();
10894                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10895                    if (!mController.appCrashed(name, pid,
10896                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10897                        Slog.w(TAG, "Force-killing crashed app " + name
10898                                + " at watcher's request");
10899                        Process.killProcess(pid);
10900                        if (r != null) {
10901                            Process.killProcessGroup(uid, pid);
10902                        }
10903                        return;
10904                    }
10905                } catch (RemoteException e) {
10906                    mController = null;
10907                    Watchdog.getInstance().setActivityController(null);
10908                }
10909            }
10910
10911            final long origId = Binder.clearCallingIdentity();
10912
10913            // If this process is running instrumentation, finish it.
10914            if (r != null && r.instrumentationClass != null) {
10915                Slog.w(TAG, "Error in app " + r.processName
10916                      + " running instrumentation " + r.instrumentationClass + ":");
10917                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10918                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10919                Bundle info = new Bundle();
10920                info.putString("shortMsg", shortMsg);
10921                info.putString("longMsg", longMsg);
10922                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10923                Binder.restoreCallingIdentity(origId);
10924                return;
10925            }
10926
10927            // If we can't identify the process or it's already exceeded its crash quota,
10928            // quit right away without showing a crash dialog.
10929            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10930                Binder.restoreCallingIdentity(origId);
10931                return;
10932            }
10933
10934            Message msg = Message.obtain();
10935            msg.what = SHOW_ERROR_MSG;
10936            HashMap data = new HashMap();
10937            data.put("result", result);
10938            data.put("app", r);
10939            msg.obj = data;
10940            mHandler.sendMessage(msg);
10941
10942            Binder.restoreCallingIdentity(origId);
10943        }
10944
10945        int res = result.get();
10946
10947        Intent appErrorIntent = null;
10948        synchronized (this) {
10949            if (r != null && !r.isolated) {
10950                // XXX Can't keep track of crash time for isolated processes,
10951                // since they don't have a persistent identity.
10952                mProcessCrashTimes.put(r.info.processName, r.uid,
10953                        SystemClock.uptimeMillis());
10954            }
10955            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10956                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10957            }
10958        }
10959
10960        if (appErrorIntent != null) {
10961            try {
10962                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10963            } catch (ActivityNotFoundException e) {
10964                Slog.w(TAG, "bug report receiver dissappeared", e);
10965            }
10966        }
10967    }
10968
10969    Intent createAppErrorIntentLocked(ProcessRecord r,
10970            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10971        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10972        if (report == null) {
10973            return null;
10974        }
10975        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10976        result.setComponent(r.errorReportReceiver);
10977        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10978        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10979        return result;
10980    }
10981
10982    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10983            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10984        if (r.errorReportReceiver == null) {
10985            return null;
10986        }
10987
10988        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10989            return null;
10990        }
10991
10992        ApplicationErrorReport report = new ApplicationErrorReport();
10993        report.packageName = r.info.packageName;
10994        report.installerPackageName = r.errorReportReceiver.getPackageName();
10995        report.processName = r.processName;
10996        report.time = timeMillis;
10997        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10998
10999        if (r.crashing || r.forceCrashReport) {
11000            report.type = ApplicationErrorReport.TYPE_CRASH;
11001            report.crashInfo = crashInfo;
11002        } else if (r.notResponding) {
11003            report.type = ApplicationErrorReport.TYPE_ANR;
11004            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11005
11006            report.anrInfo.activity = r.notRespondingReport.tag;
11007            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11008            report.anrInfo.info = r.notRespondingReport.longMsg;
11009        }
11010
11011        return report;
11012    }
11013
11014    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11015        enforceNotIsolatedCaller("getProcessesInErrorState");
11016        // assume our apps are happy - lazy create the list
11017        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11018
11019        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11020                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11021        int userId = UserHandle.getUserId(Binder.getCallingUid());
11022
11023        synchronized (this) {
11024
11025            // iterate across all processes
11026            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11027                ProcessRecord app = mLruProcesses.get(i);
11028                if (!allUsers && app.userId != userId) {
11029                    continue;
11030                }
11031                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11032                    // This one's in trouble, so we'll generate a report for it
11033                    // crashes are higher priority (in case there's a crash *and* an anr)
11034                    ActivityManager.ProcessErrorStateInfo report = null;
11035                    if (app.crashing) {
11036                        report = app.crashingReport;
11037                    } else if (app.notResponding) {
11038                        report = app.notRespondingReport;
11039                    }
11040
11041                    if (report != null) {
11042                        if (errList == null) {
11043                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11044                        }
11045                        errList.add(report);
11046                    } else {
11047                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11048                                " crashing = " + app.crashing +
11049                                " notResponding = " + app.notResponding);
11050                    }
11051                }
11052            }
11053        }
11054
11055        return errList;
11056    }
11057
11058    static int procStateToImportance(int procState, int memAdj,
11059            ActivityManager.RunningAppProcessInfo currApp) {
11060        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11061        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11062            currApp.lru = memAdj;
11063        } else {
11064            currApp.lru = 0;
11065        }
11066        return imp;
11067    }
11068
11069    private void fillInProcMemInfo(ProcessRecord app,
11070            ActivityManager.RunningAppProcessInfo outInfo) {
11071        outInfo.pid = app.pid;
11072        outInfo.uid = app.info.uid;
11073        if (mHeavyWeightProcess == app) {
11074            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11075        }
11076        if (app.persistent) {
11077            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11078        }
11079        if (app.activities.size() > 0) {
11080            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11081        }
11082        outInfo.lastTrimLevel = app.trimMemoryLevel;
11083        int adj = app.curAdj;
11084        int procState = app.curProcState;
11085        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11086        outInfo.importanceReasonCode = app.adjTypeCode;
11087        outInfo.processState = app.curProcState;
11088    }
11089
11090    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11091        enforceNotIsolatedCaller("getRunningAppProcesses");
11092        // Lazy instantiation of list
11093        List<ActivityManager.RunningAppProcessInfo> runList = null;
11094        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11095                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11096        int userId = UserHandle.getUserId(Binder.getCallingUid());
11097        synchronized (this) {
11098            // Iterate across all processes
11099            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11100                ProcessRecord app = mLruProcesses.get(i);
11101                if (!allUsers && app.userId != userId) {
11102                    continue;
11103                }
11104                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11105                    // Generate process state info for running application
11106                    ActivityManager.RunningAppProcessInfo currApp =
11107                        new ActivityManager.RunningAppProcessInfo(app.processName,
11108                                app.pid, app.getPackageList());
11109                    fillInProcMemInfo(app, currApp);
11110                    if (app.adjSource instanceof ProcessRecord) {
11111                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11112                        currApp.importanceReasonImportance =
11113                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11114                                        app.adjSourceProcState);
11115                    } else if (app.adjSource instanceof ActivityRecord) {
11116                        ActivityRecord r = (ActivityRecord)app.adjSource;
11117                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11118                    }
11119                    if (app.adjTarget instanceof ComponentName) {
11120                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11121                    }
11122                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11123                    //        + " lru=" + currApp.lru);
11124                    if (runList == null) {
11125                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11126                    }
11127                    runList.add(currApp);
11128                }
11129            }
11130        }
11131        return runList;
11132    }
11133
11134    public List<ApplicationInfo> getRunningExternalApplications() {
11135        enforceNotIsolatedCaller("getRunningExternalApplications");
11136        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11137        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11138        if (runningApps != null && runningApps.size() > 0) {
11139            Set<String> extList = new HashSet<String>();
11140            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11141                if (app.pkgList != null) {
11142                    for (String pkg : app.pkgList) {
11143                        extList.add(pkg);
11144                    }
11145                }
11146            }
11147            IPackageManager pm = AppGlobals.getPackageManager();
11148            for (String pkg : extList) {
11149                try {
11150                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11151                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11152                        retList.add(info);
11153                    }
11154                } catch (RemoteException e) {
11155                }
11156            }
11157        }
11158        return retList;
11159    }
11160
11161    @Override
11162    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11163        enforceNotIsolatedCaller("getMyMemoryState");
11164        synchronized (this) {
11165            ProcessRecord proc;
11166            synchronized (mPidsSelfLocked) {
11167                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11168            }
11169            fillInProcMemInfo(proc, outInfo);
11170        }
11171    }
11172
11173    @Override
11174    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11175        if (checkCallingPermission(android.Manifest.permission.DUMP)
11176                != PackageManager.PERMISSION_GRANTED) {
11177            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11178                    + Binder.getCallingPid()
11179                    + ", uid=" + Binder.getCallingUid()
11180                    + " without permission "
11181                    + android.Manifest.permission.DUMP);
11182            return;
11183        }
11184
11185        boolean dumpAll = false;
11186        boolean dumpClient = false;
11187        String dumpPackage = null;
11188
11189        int opti = 0;
11190        while (opti < args.length) {
11191            String opt = args[opti];
11192            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11193                break;
11194            }
11195            opti++;
11196            if ("-a".equals(opt)) {
11197                dumpAll = true;
11198            } else if ("-c".equals(opt)) {
11199                dumpClient = true;
11200            } else if ("-h".equals(opt)) {
11201                pw.println("Activity manager dump options:");
11202                pw.println("  [-a] [-c] [-h] [cmd] ...");
11203                pw.println("  cmd may be one of:");
11204                pw.println("    a[ctivities]: activity stack state");
11205                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11206                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11207                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11208                pw.println("    o[om]: out of memory management");
11209                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11210                pw.println("    provider [COMP_SPEC]: provider client-side state");
11211                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11212                pw.println("    service [COMP_SPEC]: service client-side state");
11213                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11214                pw.println("    all: dump all activities");
11215                pw.println("    top: dump the top activity");
11216                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11217                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11218                pw.println("    a partial substring in a component name, a");
11219                pw.println("    hex object identifier.");
11220                pw.println("  -a: include all available server state.");
11221                pw.println("  -c: include client state.");
11222                return;
11223            } else {
11224                pw.println("Unknown argument: " + opt + "; use -h for help");
11225            }
11226        }
11227
11228        long origId = Binder.clearCallingIdentity();
11229        boolean more = false;
11230        // Is the caller requesting to dump a particular piece of data?
11231        if (opti < args.length) {
11232            String cmd = args[opti];
11233            opti++;
11234            if ("activities".equals(cmd) || "a".equals(cmd)) {
11235                synchronized (this) {
11236                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11237                }
11238            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11239                String[] newArgs;
11240                String name;
11241                if (opti >= args.length) {
11242                    name = null;
11243                    newArgs = EMPTY_STRING_ARRAY;
11244                } else {
11245                    name = args[opti];
11246                    opti++;
11247                    newArgs = new String[args.length - opti];
11248                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11249                            args.length - opti);
11250                }
11251                synchronized (this) {
11252                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11253                }
11254            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11255                String[] newArgs;
11256                String name;
11257                if (opti >= args.length) {
11258                    name = null;
11259                    newArgs = EMPTY_STRING_ARRAY;
11260                } else {
11261                    name = args[opti];
11262                    opti++;
11263                    newArgs = new String[args.length - opti];
11264                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11265                            args.length - opti);
11266                }
11267                synchronized (this) {
11268                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11269                }
11270            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11271                String[] newArgs;
11272                String name;
11273                if (opti >= args.length) {
11274                    name = null;
11275                    newArgs = EMPTY_STRING_ARRAY;
11276                } else {
11277                    name = args[opti];
11278                    opti++;
11279                    newArgs = new String[args.length - opti];
11280                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11281                            args.length - opti);
11282                }
11283                synchronized (this) {
11284                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11285                }
11286            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11287                synchronized (this) {
11288                    dumpOomLocked(fd, pw, args, opti, true);
11289                }
11290            } else if ("provider".equals(cmd)) {
11291                String[] newArgs;
11292                String name;
11293                if (opti >= args.length) {
11294                    name = null;
11295                    newArgs = EMPTY_STRING_ARRAY;
11296                } else {
11297                    name = args[opti];
11298                    opti++;
11299                    newArgs = new String[args.length - opti];
11300                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11301                }
11302                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11303                    pw.println("No providers match: " + name);
11304                    pw.println("Use -h for help.");
11305                }
11306            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11307                synchronized (this) {
11308                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11309                }
11310            } else if ("service".equals(cmd)) {
11311                String[] newArgs;
11312                String name;
11313                if (opti >= args.length) {
11314                    name = null;
11315                    newArgs = EMPTY_STRING_ARRAY;
11316                } else {
11317                    name = args[opti];
11318                    opti++;
11319                    newArgs = new String[args.length - opti];
11320                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11321                            args.length - opti);
11322                }
11323                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11324                    pw.println("No services match: " + name);
11325                    pw.println("Use -h for help.");
11326                }
11327            } else if ("package".equals(cmd)) {
11328                String[] newArgs;
11329                if (opti >= args.length) {
11330                    pw.println("package: no package name specified");
11331                    pw.println("Use -h for help.");
11332                } else {
11333                    dumpPackage = args[opti];
11334                    opti++;
11335                    newArgs = new String[args.length - opti];
11336                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11337                            args.length - opti);
11338                    args = newArgs;
11339                    opti = 0;
11340                    more = true;
11341                }
11342            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11343                synchronized (this) {
11344                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11345                }
11346            } else {
11347                // Dumping a single activity?
11348                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11349                    pw.println("Bad activity command, or no activities match: " + cmd);
11350                    pw.println("Use -h for help.");
11351                }
11352            }
11353            if (!more) {
11354                Binder.restoreCallingIdentity(origId);
11355                return;
11356            }
11357        }
11358
11359        // No piece of data specified, dump everything.
11360        synchronized (this) {
11361            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11362            pw.println();
11363            if (dumpAll) {
11364                pw.println("-------------------------------------------------------------------------------");
11365            }
11366            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11367            pw.println();
11368            if (dumpAll) {
11369                pw.println("-------------------------------------------------------------------------------");
11370            }
11371            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11372            pw.println();
11373            if (dumpAll) {
11374                pw.println("-------------------------------------------------------------------------------");
11375            }
11376            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11377            pw.println();
11378            if (dumpAll) {
11379                pw.println("-------------------------------------------------------------------------------");
11380            }
11381            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11382            pw.println();
11383            if (dumpAll) {
11384                pw.println("-------------------------------------------------------------------------------");
11385            }
11386            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11387        }
11388        Binder.restoreCallingIdentity(origId);
11389    }
11390
11391    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11392            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11393        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11394
11395        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11396                dumpPackage);
11397        boolean needSep = printedAnything;
11398
11399        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11400                dumpPackage, needSep, "  mFocusedActivity: ");
11401        if (printed) {
11402            printedAnything = true;
11403            needSep = false;
11404        }
11405
11406        if (dumpPackage == null) {
11407            if (needSep) {
11408                pw.println();
11409            }
11410            needSep = true;
11411            printedAnything = true;
11412            mStackSupervisor.dump(pw, "  ");
11413        }
11414
11415        if (mRecentTasks.size() > 0) {
11416            boolean printedHeader = false;
11417
11418            final int N = mRecentTasks.size();
11419            for (int i=0; i<N; i++) {
11420                TaskRecord tr = mRecentTasks.get(i);
11421                if (dumpPackage != null) {
11422                    if (tr.realActivity == null ||
11423                            !dumpPackage.equals(tr.realActivity)) {
11424                        continue;
11425                    }
11426                }
11427                if (!printedHeader) {
11428                    if (needSep) {
11429                        pw.println();
11430                    }
11431                    pw.println("  Recent tasks:");
11432                    printedHeader = true;
11433                    printedAnything = true;
11434                }
11435                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11436                        pw.println(tr);
11437                if (dumpAll) {
11438                    mRecentTasks.get(i).dump(pw, "    ");
11439                }
11440            }
11441        }
11442
11443        if (!printedAnything) {
11444            pw.println("  (nothing)");
11445        }
11446    }
11447
11448    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11449            int opti, boolean dumpAll, String dumpPackage) {
11450        boolean needSep = false;
11451        boolean printedAnything = false;
11452        int numPers = 0;
11453
11454        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11455
11456        if (dumpAll) {
11457            final int NP = mProcessNames.getMap().size();
11458            for (int ip=0; ip<NP; ip++) {
11459                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11460                final int NA = procs.size();
11461                for (int ia=0; ia<NA; ia++) {
11462                    ProcessRecord r = procs.valueAt(ia);
11463                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11464                        continue;
11465                    }
11466                    if (!needSep) {
11467                        pw.println("  All known processes:");
11468                        needSep = true;
11469                        printedAnything = true;
11470                    }
11471                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11472                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11473                        pw.print(" "); pw.println(r);
11474                    r.dump(pw, "    ");
11475                    if (r.persistent) {
11476                        numPers++;
11477                    }
11478                }
11479            }
11480        }
11481
11482        if (mIsolatedProcesses.size() > 0) {
11483            boolean printed = false;
11484            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11485                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11486                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11487                    continue;
11488                }
11489                if (!printed) {
11490                    if (needSep) {
11491                        pw.println();
11492                    }
11493                    pw.println("  Isolated process list (sorted by uid):");
11494                    printedAnything = true;
11495                    printed = true;
11496                    needSep = true;
11497                }
11498                pw.println(String.format("%sIsolated #%2d: %s",
11499                        "    ", i, r.toString()));
11500            }
11501        }
11502
11503        if (mLruProcesses.size() > 0) {
11504            if (needSep) {
11505                pw.println();
11506            }
11507            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11508                    pw.print(" total, non-act at ");
11509                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11510                    pw.print(", non-svc at ");
11511                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11512                    pw.println("):");
11513            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11514            needSep = true;
11515            printedAnything = true;
11516        }
11517
11518        if (dumpAll || dumpPackage != null) {
11519            synchronized (mPidsSelfLocked) {
11520                boolean printed = false;
11521                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11522                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11523                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11524                        continue;
11525                    }
11526                    if (!printed) {
11527                        if (needSep) pw.println();
11528                        needSep = true;
11529                        pw.println("  PID mappings:");
11530                        printed = true;
11531                        printedAnything = true;
11532                    }
11533                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11534                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11535                }
11536            }
11537        }
11538
11539        if (mForegroundProcesses.size() > 0) {
11540            synchronized (mPidsSelfLocked) {
11541                boolean printed = false;
11542                for (int i=0; i<mForegroundProcesses.size(); i++) {
11543                    ProcessRecord r = mPidsSelfLocked.get(
11544                            mForegroundProcesses.valueAt(i).pid);
11545                    if (dumpPackage != null && (r == null
11546                            || !r.pkgList.containsKey(dumpPackage))) {
11547                        continue;
11548                    }
11549                    if (!printed) {
11550                        if (needSep) pw.println();
11551                        needSep = true;
11552                        pw.println("  Foreground Processes:");
11553                        printed = true;
11554                        printedAnything = true;
11555                    }
11556                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11557                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11558                }
11559            }
11560        }
11561
11562        if (mPersistentStartingProcesses.size() > 0) {
11563            if (needSep) pw.println();
11564            needSep = true;
11565            printedAnything = true;
11566            pw.println("  Persisent processes that are starting:");
11567            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11568                    "Starting Norm", "Restarting PERS", dumpPackage);
11569        }
11570
11571        if (mRemovedProcesses.size() > 0) {
11572            if (needSep) pw.println();
11573            needSep = true;
11574            printedAnything = true;
11575            pw.println("  Processes that are being removed:");
11576            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11577                    "Removed Norm", "Removed PERS", dumpPackage);
11578        }
11579
11580        if (mProcessesOnHold.size() > 0) {
11581            if (needSep) pw.println();
11582            needSep = true;
11583            printedAnything = true;
11584            pw.println("  Processes that are on old until the system is ready:");
11585            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11586                    "OnHold Norm", "OnHold PERS", dumpPackage);
11587        }
11588
11589        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11590
11591        if (mProcessCrashTimes.getMap().size() > 0) {
11592            boolean printed = false;
11593            long now = SystemClock.uptimeMillis();
11594            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11595            final int NP = pmap.size();
11596            for (int ip=0; ip<NP; ip++) {
11597                String pname = pmap.keyAt(ip);
11598                SparseArray<Long> uids = pmap.valueAt(ip);
11599                final int N = uids.size();
11600                for (int i=0; i<N; i++) {
11601                    int puid = uids.keyAt(i);
11602                    ProcessRecord r = mProcessNames.get(pname, puid);
11603                    if (dumpPackage != null && (r == null
11604                            || !r.pkgList.containsKey(dumpPackage))) {
11605                        continue;
11606                    }
11607                    if (!printed) {
11608                        if (needSep) pw.println();
11609                        needSep = true;
11610                        pw.println("  Time since processes crashed:");
11611                        printed = true;
11612                        printedAnything = true;
11613                    }
11614                    pw.print("    Process "); pw.print(pname);
11615                            pw.print(" uid "); pw.print(puid);
11616                            pw.print(": last crashed ");
11617                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11618                            pw.println(" ago");
11619                }
11620            }
11621        }
11622
11623        if (mBadProcesses.getMap().size() > 0) {
11624            boolean printed = false;
11625            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11626            final int NP = pmap.size();
11627            for (int ip=0; ip<NP; ip++) {
11628                String pname = pmap.keyAt(ip);
11629                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11630                final int N = uids.size();
11631                for (int i=0; i<N; i++) {
11632                    int puid = uids.keyAt(i);
11633                    ProcessRecord r = mProcessNames.get(pname, puid);
11634                    if (dumpPackage != null && (r == null
11635                            || !r.pkgList.containsKey(dumpPackage))) {
11636                        continue;
11637                    }
11638                    if (!printed) {
11639                        if (needSep) pw.println();
11640                        needSep = true;
11641                        pw.println("  Bad processes:");
11642                        printedAnything = true;
11643                    }
11644                    BadProcessInfo info = uids.valueAt(i);
11645                    pw.print("    Bad process "); pw.print(pname);
11646                            pw.print(" uid "); pw.print(puid);
11647                            pw.print(": crashed at time "); pw.println(info.time);
11648                    if (info.shortMsg != null) {
11649                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11650                    }
11651                    if (info.longMsg != null) {
11652                        pw.print("      Long msg: "); pw.println(info.longMsg);
11653                    }
11654                    if (info.stack != null) {
11655                        pw.println("      Stack:");
11656                        int lastPos = 0;
11657                        for (int pos=0; pos<info.stack.length(); pos++) {
11658                            if (info.stack.charAt(pos) == '\n') {
11659                                pw.print("        ");
11660                                pw.write(info.stack, lastPos, pos-lastPos);
11661                                pw.println();
11662                                lastPos = pos+1;
11663                            }
11664                        }
11665                        if (lastPos < info.stack.length()) {
11666                            pw.print("        ");
11667                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11668                            pw.println();
11669                        }
11670                    }
11671                }
11672            }
11673        }
11674
11675        if (dumpPackage == null) {
11676            pw.println();
11677            needSep = false;
11678            pw.println("  mStartedUsers:");
11679            for (int i=0; i<mStartedUsers.size(); i++) {
11680                UserStartedState uss = mStartedUsers.valueAt(i);
11681                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11682                        pw.print(": "); uss.dump("", pw);
11683            }
11684            pw.print("  mStartedUserArray: [");
11685            for (int i=0; i<mStartedUserArray.length; i++) {
11686                if (i > 0) pw.print(", ");
11687                pw.print(mStartedUserArray[i]);
11688            }
11689            pw.println("]");
11690            pw.print("  mUserLru: [");
11691            for (int i=0; i<mUserLru.size(); i++) {
11692                if (i > 0) pw.print(", ");
11693                pw.print(mUserLru.get(i));
11694            }
11695            pw.println("]");
11696            if (dumpAll) {
11697                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11698            }
11699            synchronized (mUserProfileGroupIdsSelfLocked) {
11700                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11701                    pw.println("  mUserProfileGroupIds:");
11702                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11703                        pw.print("    User #");
11704                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11705                        pw.print(" -> profile #");
11706                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11707                    }
11708                }
11709            }
11710        }
11711        if (mHomeProcess != null && (dumpPackage == null
11712                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11713            if (needSep) {
11714                pw.println();
11715                needSep = false;
11716            }
11717            pw.println("  mHomeProcess: " + mHomeProcess);
11718        }
11719        if (mPreviousProcess != null && (dumpPackage == null
11720                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11721            if (needSep) {
11722                pw.println();
11723                needSep = false;
11724            }
11725            pw.println("  mPreviousProcess: " + mPreviousProcess);
11726        }
11727        if (dumpAll) {
11728            StringBuilder sb = new StringBuilder(128);
11729            sb.append("  mPreviousProcessVisibleTime: ");
11730            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11731            pw.println(sb);
11732        }
11733        if (mHeavyWeightProcess != null && (dumpPackage == null
11734                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11735            if (needSep) {
11736                pw.println();
11737                needSep = false;
11738            }
11739            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11740        }
11741        if (dumpPackage == null) {
11742            pw.println("  mConfiguration: " + mConfiguration);
11743        }
11744        if (dumpAll) {
11745            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11746            if (mCompatModePackages.getPackages().size() > 0) {
11747                boolean printed = false;
11748                for (Map.Entry<String, Integer> entry
11749                        : mCompatModePackages.getPackages().entrySet()) {
11750                    String pkg = entry.getKey();
11751                    int mode = entry.getValue();
11752                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11753                        continue;
11754                    }
11755                    if (!printed) {
11756                        pw.println("  mScreenCompatPackages:");
11757                        printed = true;
11758                    }
11759                    pw.print("    "); pw.print(pkg); pw.print(": ");
11760                            pw.print(mode); pw.println();
11761                }
11762            }
11763        }
11764        if (dumpPackage == null) {
11765            if (mSleeping || mWentToSleep || mLockScreenShown) {
11766                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11767                        + " mLockScreenShown " + mLockScreenShown);
11768            }
11769            if (mShuttingDown || mRunningVoice) {
11770                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11771            }
11772        }
11773        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11774                || mOrigWaitForDebugger) {
11775            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11776                    || dumpPackage.equals(mOrigDebugApp)) {
11777                if (needSep) {
11778                    pw.println();
11779                    needSep = false;
11780                }
11781                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11782                        + " mDebugTransient=" + mDebugTransient
11783                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11784            }
11785        }
11786        if (mOpenGlTraceApp != null) {
11787            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11788                if (needSep) {
11789                    pw.println();
11790                    needSep = false;
11791                }
11792                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11793            }
11794        }
11795        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11796                || mProfileFd != null) {
11797            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11798                if (needSep) {
11799                    pw.println();
11800                    needSep = false;
11801                }
11802                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11803                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11804                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11805                        + mAutoStopProfiler);
11806            }
11807        }
11808        if (dumpPackage == null) {
11809            if (mAlwaysFinishActivities || mController != null) {
11810                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11811                        + " mController=" + mController);
11812            }
11813            if (dumpAll) {
11814                pw.println("  Total persistent processes: " + numPers);
11815                pw.println("  mProcessesReady=" + mProcessesReady
11816                        + " mSystemReady=" + mSystemReady);
11817                pw.println("  mBooting=" + mBooting
11818                        + " mBooted=" + mBooted
11819                        + " mFactoryTest=" + mFactoryTest);
11820                pw.print("  mLastPowerCheckRealtime=");
11821                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11822                        pw.println("");
11823                pw.print("  mLastPowerCheckUptime=");
11824                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11825                        pw.println("");
11826                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11827                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11828                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11829                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11830                        + " (" + mLruProcesses.size() + " total)"
11831                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11832                        + " mNumServiceProcs=" + mNumServiceProcs
11833                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11834                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11835                        + " mLastMemoryLevel" + mLastMemoryLevel
11836                        + " mLastNumProcesses" + mLastNumProcesses);
11837                long now = SystemClock.uptimeMillis();
11838                pw.print("  mLastIdleTime=");
11839                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11840                        pw.print(" mLowRamSinceLastIdle=");
11841                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11842                        pw.println();
11843            }
11844        }
11845
11846        if (!printedAnything) {
11847            pw.println("  (nothing)");
11848        }
11849    }
11850
11851    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11852            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11853        if (mProcessesToGc.size() > 0) {
11854            boolean printed = false;
11855            long now = SystemClock.uptimeMillis();
11856            for (int i=0; i<mProcessesToGc.size(); i++) {
11857                ProcessRecord proc = mProcessesToGc.get(i);
11858                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11859                    continue;
11860                }
11861                if (!printed) {
11862                    if (needSep) pw.println();
11863                    needSep = true;
11864                    pw.println("  Processes that are waiting to GC:");
11865                    printed = true;
11866                }
11867                pw.print("    Process "); pw.println(proc);
11868                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11869                        pw.print(", last gced=");
11870                        pw.print(now-proc.lastRequestedGc);
11871                        pw.print(" ms ago, last lowMem=");
11872                        pw.print(now-proc.lastLowMemory);
11873                        pw.println(" ms ago");
11874
11875            }
11876        }
11877        return needSep;
11878    }
11879
11880    void printOomLevel(PrintWriter pw, String name, int adj) {
11881        pw.print("    ");
11882        if (adj >= 0) {
11883            pw.print(' ');
11884            if (adj < 10) pw.print(' ');
11885        } else {
11886            if (adj > -10) pw.print(' ');
11887        }
11888        pw.print(adj);
11889        pw.print(": ");
11890        pw.print(name);
11891        pw.print(" (");
11892        pw.print(mProcessList.getMemLevel(adj)/1024);
11893        pw.println(" kB)");
11894    }
11895
11896    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11897            int opti, boolean dumpAll) {
11898        boolean needSep = false;
11899
11900        if (mLruProcesses.size() > 0) {
11901            if (needSep) pw.println();
11902            needSep = true;
11903            pw.println("  OOM levels:");
11904            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11905            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11906            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11907            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11908            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11909            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11910            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11911            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11912            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11913            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11914            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11915            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11916            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11917
11918            if (needSep) pw.println();
11919            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11920                    pw.print(" total, non-act at ");
11921                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11922                    pw.print(", non-svc at ");
11923                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11924                    pw.println("):");
11925            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11926            needSep = true;
11927        }
11928
11929        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11930
11931        pw.println();
11932        pw.println("  mHomeProcess: " + mHomeProcess);
11933        pw.println("  mPreviousProcess: " + mPreviousProcess);
11934        if (mHeavyWeightProcess != null) {
11935            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11936        }
11937
11938        return true;
11939    }
11940
11941    /**
11942     * There are three ways to call this:
11943     *  - no provider specified: dump all the providers
11944     *  - a flattened component name that matched an existing provider was specified as the
11945     *    first arg: dump that one provider
11946     *  - the first arg isn't the flattened component name of an existing provider:
11947     *    dump all providers whose component contains the first arg as a substring
11948     */
11949    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11950            int opti, boolean dumpAll) {
11951        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11952    }
11953
11954    static class ItemMatcher {
11955        ArrayList<ComponentName> components;
11956        ArrayList<String> strings;
11957        ArrayList<Integer> objects;
11958        boolean all;
11959
11960        ItemMatcher() {
11961            all = true;
11962        }
11963
11964        void build(String name) {
11965            ComponentName componentName = ComponentName.unflattenFromString(name);
11966            if (componentName != null) {
11967                if (components == null) {
11968                    components = new ArrayList<ComponentName>();
11969                }
11970                components.add(componentName);
11971                all = false;
11972            } else {
11973                int objectId = 0;
11974                // Not a '/' separated full component name; maybe an object ID?
11975                try {
11976                    objectId = Integer.parseInt(name, 16);
11977                    if (objects == null) {
11978                        objects = new ArrayList<Integer>();
11979                    }
11980                    objects.add(objectId);
11981                    all = false;
11982                } catch (RuntimeException e) {
11983                    // Not an integer; just do string match.
11984                    if (strings == null) {
11985                        strings = new ArrayList<String>();
11986                    }
11987                    strings.add(name);
11988                    all = false;
11989                }
11990            }
11991        }
11992
11993        int build(String[] args, int opti) {
11994            for (; opti<args.length; opti++) {
11995                String name = args[opti];
11996                if ("--".equals(name)) {
11997                    return opti+1;
11998                }
11999                build(name);
12000            }
12001            return opti;
12002        }
12003
12004        boolean match(Object object, ComponentName comp) {
12005            if (all) {
12006                return true;
12007            }
12008            if (components != null) {
12009                for (int i=0; i<components.size(); i++) {
12010                    if (components.get(i).equals(comp)) {
12011                        return true;
12012                    }
12013                }
12014            }
12015            if (objects != null) {
12016                for (int i=0; i<objects.size(); i++) {
12017                    if (System.identityHashCode(object) == objects.get(i)) {
12018                        return true;
12019                    }
12020                }
12021            }
12022            if (strings != null) {
12023                String flat = comp.flattenToString();
12024                for (int i=0; i<strings.size(); i++) {
12025                    if (flat.contains(strings.get(i))) {
12026                        return true;
12027                    }
12028                }
12029            }
12030            return false;
12031        }
12032    }
12033
12034    /**
12035     * There are three things that cmd can be:
12036     *  - a flattened component name that matches an existing activity
12037     *  - the cmd arg isn't the flattened component name of an existing activity:
12038     *    dump all activity whose component contains the cmd as a substring
12039     *  - A hex number of the ActivityRecord object instance.
12040     */
12041    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12042            int opti, boolean dumpAll) {
12043        ArrayList<ActivityRecord> activities;
12044
12045        synchronized (this) {
12046            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12047        }
12048
12049        if (activities.size() <= 0) {
12050            return false;
12051        }
12052
12053        String[] newArgs = new String[args.length - opti];
12054        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12055
12056        TaskRecord lastTask = null;
12057        boolean needSep = false;
12058        for (int i=activities.size()-1; i>=0; i--) {
12059            ActivityRecord r = activities.get(i);
12060            if (needSep) {
12061                pw.println();
12062            }
12063            needSep = true;
12064            synchronized (this) {
12065                if (lastTask != r.task) {
12066                    lastTask = r.task;
12067                    pw.print("TASK "); pw.print(lastTask.affinity);
12068                            pw.print(" id="); pw.println(lastTask.taskId);
12069                    if (dumpAll) {
12070                        lastTask.dump(pw, "  ");
12071                    }
12072                }
12073            }
12074            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12075        }
12076        return true;
12077    }
12078
12079    /**
12080     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12081     * there is a thread associated with the activity.
12082     */
12083    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12084            final ActivityRecord r, String[] args, boolean dumpAll) {
12085        String innerPrefix = prefix + "  ";
12086        synchronized (this) {
12087            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12088                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12089                    pw.print(" pid=");
12090                    if (r.app != null) pw.println(r.app.pid);
12091                    else pw.println("(not running)");
12092            if (dumpAll) {
12093                r.dump(pw, innerPrefix);
12094            }
12095        }
12096        if (r.app != null && r.app.thread != null) {
12097            // flush anything that is already in the PrintWriter since the thread is going
12098            // to write to the file descriptor directly
12099            pw.flush();
12100            try {
12101                TransferPipe tp = new TransferPipe();
12102                try {
12103                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12104                            r.appToken, innerPrefix, args);
12105                    tp.go(fd);
12106                } finally {
12107                    tp.kill();
12108                }
12109            } catch (IOException e) {
12110                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12111            } catch (RemoteException e) {
12112                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12113            }
12114        }
12115    }
12116
12117    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12118            int opti, boolean dumpAll, String dumpPackage) {
12119        boolean needSep = false;
12120        boolean onlyHistory = false;
12121        boolean printedAnything = false;
12122
12123        if ("history".equals(dumpPackage)) {
12124            if (opti < args.length && "-s".equals(args[opti])) {
12125                dumpAll = false;
12126            }
12127            onlyHistory = true;
12128            dumpPackage = null;
12129        }
12130
12131        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12132        if (!onlyHistory && dumpAll) {
12133            if (mRegisteredReceivers.size() > 0) {
12134                boolean printed = false;
12135                Iterator it = mRegisteredReceivers.values().iterator();
12136                while (it.hasNext()) {
12137                    ReceiverList r = (ReceiverList)it.next();
12138                    if (dumpPackage != null && (r.app == null ||
12139                            !dumpPackage.equals(r.app.info.packageName))) {
12140                        continue;
12141                    }
12142                    if (!printed) {
12143                        pw.println("  Registered Receivers:");
12144                        needSep = true;
12145                        printed = true;
12146                        printedAnything = true;
12147                    }
12148                    pw.print("  * "); pw.println(r);
12149                    r.dump(pw, "    ");
12150                }
12151            }
12152
12153            if (mReceiverResolver.dump(pw, needSep ?
12154                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12155                    "    ", dumpPackage, false)) {
12156                needSep = true;
12157                printedAnything = true;
12158            }
12159        }
12160
12161        for (BroadcastQueue q : mBroadcastQueues) {
12162            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12163            printedAnything |= needSep;
12164        }
12165
12166        needSep = true;
12167
12168        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12169            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12170                if (needSep) {
12171                    pw.println();
12172                }
12173                needSep = true;
12174                printedAnything = true;
12175                pw.print("  Sticky broadcasts for user ");
12176                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12177                StringBuilder sb = new StringBuilder(128);
12178                for (Map.Entry<String, ArrayList<Intent>> ent
12179                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12180                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12181                    if (dumpAll) {
12182                        pw.println(":");
12183                        ArrayList<Intent> intents = ent.getValue();
12184                        final int N = intents.size();
12185                        for (int i=0; i<N; i++) {
12186                            sb.setLength(0);
12187                            sb.append("    Intent: ");
12188                            intents.get(i).toShortString(sb, false, true, false, false);
12189                            pw.println(sb.toString());
12190                            Bundle bundle = intents.get(i).getExtras();
12191                            if (bundle != null) {
12192                                pw.print("      ");
12193                                pw.println(bundle.toString());
12194                            }
12195                        }
12196                    } else {
12197                        pw.println("");
12198                    }
12199                }
12200            }
12201        }
12202
12203        if (!onlyHistory && dumpAll) {
12204            pw.println();
12205            for (BroadcastQueue queue : mBroadcastQueues) {
12206                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12207                        + queue.mBroadcastsScheduled);
12208            }
12209            pw.println("  mHandler:");
12210            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12211            needSep = true;
12212            printedAnything = true;
12213        }
12214
12215        if (!printedAnything) {
12216            pw.println("  (nothing)");
12217        }
12218    }
12219
12220    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12221            int opti, boolean dumpAll, String dumpPackage) {
12222        boolean needSep;
12223        boolean printedAnything = false;
12224
12225        ItemMatcher matcher = new ItemMatcher();
12226        matcher.build(args, opti);
12227
12228        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12229
12230        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12231        printedAnything |= needSep;
12232
12233        if (mLaunchingProviders.size() > 0) {
12234            boolean printed = false;
12235            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12236                ContentProviderRecord r = mLaunchingProviders.get(i);
12237                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12238                    continue;
12239                }
12240                if (!printed) {
12241                    if (needSep) pw.println();
12242                    needSep = true;
12243                    pw.println("  Launching content providers:");
12244                    printed = true;
12245                    printedAnything = true;
12246                }
12247                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12248                        pw.println(r);
12249            }
12250        }
12251
12252        if (mGrantedUriPermissions.size() > 0) {
12253            boolean printed = false;
12254            int dumpUid = -2;
12255            if (dumpPackage != null) {
12256                try {
12257                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12258                } catch (NameNotFoundException e) {
12259                    dumpUid = -1;
12260                }
12261            }
12262            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12263                int uid = mGrantedUriPermissions.keyAt(i);
12264                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12265                    continue;
12266                }
12267                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12268                if (!printed) {
12269                    if (needSep) pw.println();
12270                    needSep = true;
12271                    pw.println("  Granted Uri Permissions:");
12272                    printed = true;
12273                    printedAnything = true;
12274                }
12275                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12276                for (UriPermission perm : perms.values()) {
12277                    pw.print("    "); pw.println(perm);
12278                    if (dumpAll) {
12279                        perm.dump(pw, "      ");
12280                    }
12281                }
12282            }
12283        }
12284
12285        if (!printedAnything) {
12286            pw.println("  (nothing)");
12287        }
12288    }
12289
12290    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12291            int opti, boolean dumpAll, String dumpPackage) {
12292        boolean printed = false;
12293
12294        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12295
12296        if (mIntentSenderRecords.size() > 0) {
12297            Iterator<WeakReference<PendingIntentRecord>> it
12298                    = mIntentSenderRecords.values().iterator();
12299            while (it.hasNext()) {
12300                WeakReference<PendingIntentRecord> ref = it.next();
12301                PendingIntentRecord rec = ref != null ? ref.get(): null;
12302                if (dumpPackage != null && (rec == null
12303                        || !dumpPackage.equals(rec.key.packageName))) {
12304                    continue;
12305                }
12306                printed = true;
12307                if (rec != null) {
12308                    pw.print("  * "); pw.println(rec);
12309                    if (dumpAll) {
12310                        rec.dump(pw, "    ");
12311                    }
12312                } else {
12313                    pw.print("  * "); pw.println(ref);
12314                }
12315            }
12316        }
12317
12318        if (!printed) {
12319            pw.println("  (nothing)");
12320        }
12321    }
12322
12323    private static final int dumpProcessList(PrintWriter pw,
12324            ActivityManagerService service, List list,
12325            String prefix, String normalLabel, String persistentLabel,
12326            String dumpPackage) {
12327        int numPers = 0;
12328        final int N = list.size()-1;
12329        for (int i=N; i>=0; i--) {
12330            ProcessRecord r = (ProcessRecord)list.get(i);
12331            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12332                continue;
12333            }
12334            pw.println(String.format("%s%s #%2d: %s",
12335                    prefix, (r.persistent ? persistentLabel : normalLabel),
12336                    i, r.toString()));
12337            if (r.persistent) {
12338                numPers++;
12339            }
12340        }
12341        return numPers;
12342    }
12343
12344    private static final boolean dumpProcessOomList(PrintWriter pw,
12345            ActivityManagerService service, List<ProcessRecord> origList,
12346            String prefix, String normalLabel, String persistentLabel,
12347            boolean inclDetails, String dumpPackage) {
12348
12349        ArrayList<Pair<ProcessRecord, Integer>> list
12350                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12351        for (int i=0; i<origList.size(); i++) {
12352            ProcessRecord r = origList.get(i);
12353            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12354                continue;
12355            }
12356            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12357        }
12358
12359        if (list.size() <= 0) {
12360            return false;
12361        }
12362
12363        Comparator<Pair<ProcessRecord, Integer>> comparator
12364                = new Comparator<Pair<ProcessRecord, Integer>>() {
12365            @Override
12366            public int compare(Pair<ProcessRecord, Integer> object1,
12367                    Pair<ProcessRecord, Integer> object2) {
12368                if (object1.first.setAdj != object2.first.setAdj) {
12369                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12370                }
12371                if (object1.second.intValue() != object2.second.intValue()) {
12372                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12373                }
12374                return 0;
12375            }
12376        };
12377
12378        Collections.sort(list, comparator);
12379
12380        final long curRealtime = SystemClock.elapsedRealtime();
12381        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12382        final long curUptime = SystemClock.uptimeMillis();
12383        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12384
12385        for (int i=list.size()-1; i>=0; i--) {
12386            ProcessRecord r = list.get(i).first;
12387            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12388            char schedGroup;
12389            switch (r.setSchedGroup) {
12390                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12391                    schedGroup = 'B';
12392                    break;
12393                case Process.THREAD_GROUP_DEFAULT:
12394                    schedGroup = 'F';
12395                    break;
12396                default:
12397                    schedGroup = '?';
12398                    break;
12399            }
12400            char foreground;
12401            if (r.foregroundActivities) {
12402                foreground = 'A';
12403            } else if (r.foregroundServices) {
12404                foreground = 'S';
12405            } else {
12406                foreground = ' ';
12407            }
12408            String procState = ProcessList.makeProcStateString(r.curProcState);
12409            pw.print(prefix);
12410            pw.print(r.persistent ? persistentLabel : normalLabel);
12411            pw.print(" #");
12412            int num = (origList.size()-1)-list.get(i).second;
12413            if (num < 10) pw.print(' ');
12414            pw.print(num);
12415            pw.print(": ");
12416            pw.print(oomAdj);
12417            pw.print(' ');
12418            pw.print(schedGroup);
12419            pw.print('/');
12420            pw.print(foreground);
12421            pw.print('/');
12422            pw.print(procState);
12423            pw.print(" trm:");
12424            if (r.trimMemoryLevel < 10) pw.print(' ');
12425            pw.print(r.trimMemoryLevel);
12426            pw.print(' ');
12427            pw.print(r.toShortString());
12428            pw.print(" (");
12429            pw.print(r.adjType);
12430            pw.println(')');
12431            if (r.adjSource != null || r.adjTarget != null) {
12432                pw.print(prefix);
12433                pw.print("    ");
12434                if (r.adjTarget instanceof ComponentName) {
12435                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12436                } else if (r.adjTarget != null) {
12437                    pw.print(r.adjTarget.toString());
12438                } else {
12439                    pw.print("{null}");
12440                }
12441                pw.print("<=");
12442                if (r.adjSource instanceof ProcessRecord) {
12443                    pw.print("Proc{");
12444                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12445                    pw.println("}");
12446                } else if (r.adjSource != null) {
12447                    pw.println(r.adjSource.toString());
12448                } else {
12449                    pw.println("{null}");
12450                }
12451            }
12452            if (inclDetails) {
12453                pw.print(prefix);
12454                pw.print("    ");
12455                pw.print("oom: max="); pw.print(r.maxAdj);
12456                pw.print(" curRaw="); pw.print(r.curRawAdj);
12457                pw.print(" setRaw="); pw.print(r.setRawAdj);
12458                pw.print(" cur="); pw.print(r.curAdj);
12459                pw.print(" set="); pw.println(r.setAdj);
12460                pw.print(prefix);
12461                pw.print("    ");
12462                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12463                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12464                pw.print(" lastPss="); pw.print(r.lastPss);
12465                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12466                pw.print(prefix);
12467                pw.print("    ");
12468                pw.print("cached="); pw.print(r.cached);
12469                pw.print(" empty="); pw.print(r.empty);
12470                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12471
12472                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12473                    if (r.lastWakeTime != 0) {
12474                        long wtime;
12475                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12476                        synchronized (stats) {
12477                            wtime = stats.getProcessWakeTime(r.info.uid,
12478                                    r.pid, curRealtime);
12479                        }
12480                        long timeUsed = wtime - r.lastWakeTime;
12481                        pw.print(prefix);
12482                        pw.print("    ");
12483                        pw.print("keep awake over ");
12484                        TimeUtils.formatDuration(realtimeSince, pw);
12485                        pw.print(" used ");
12486                        TimeUtils.formatDuration(timeUsed, pw);
12487                        pw.print(" (");
12488                        pw.print((timeUsed*100)/realtimeSince);
12489                        pw.println("%)");
12490                    }
12491                    if (r.lastCpuTime != 0) {
12492                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12493                        pw.print(prefix);
12494                        pw.print("    ");
12495                        pw.print("run cpu over ");
12496                        TimeUtils.formatDuration(uptimeSince, pw);
12497                        pw.print(" used ");
12498                        TimeUtils.formatDuration(timeUsed, pw);
12499                        pw.print(" (");
12500                        pw.print((timeUsed*100)/uptimeSince);
12501                        pw.println("%)");
12502                    }
12503                }
12504            }
12505        }
12506        return true;
12507    }
12508
12509    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12510        ArrayList<ProcessRecord> procs;
12511        synchronized (this) {
12512            if (args != null && args.length > start
12513                    && args[start].charAt(0) != '-') {
12514                procs = new ArrayList<ProcessRecord>();
12515                int pid = -1;
12516                try {
12517                    pid = Integer.parseInt(args[start]);
12518                } catch (NumberFormatException e) {
12519                }
12520                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12521                    ProcessRecord proc = mLruProcesses.get(i);
12522                    if (proc.pid == pid) {
12523                        procs.add(proc);
12524                    } else if (proc.processName.equals(args[start])) {
12525                        procs.add(proc);
12526                    }
12527                }
12528                if (procs.size() <= 0) {
12529                    return null;
12530                }
12531            } else {
12532                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12533            }
12534        }
12535        return procs;
12536    }
12537
12538    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12539            PrintWriter pw, String[] args) {
12540        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12541        if (procs == null) {
12542            pw.println("No process found for: " + args[0]);
12543            return;
12544        }
12545
12546        long uptime = SystemClock.uptimeMillis();
12547        long realtime = SystemClock.elapsedRealtime();
12548        pw.println("Applications Graphics Acceleration Info:");
12549        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12550
12551        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12552            ProcessRecord r = procs.get(i);
12553            if (r.thread != null) {
12554                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12555                pw.flush();
12556                try {
12557                    TransferPipe tp = new TransferPipe();
12558                    try {
12559                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12560                        tp.go(fd);
12561                    } finally {
12562                        tp.kill();
12563                    }
12564                } catch (IOException e) {
12565                    pw.println("Failure while dumping the app: " + r);
12566                    pw.flush();
12567                } catch (RemoteException e) {
12568                    pw.println("Got a RemoteException while dumping the app " + r);
12569                    pw.flush();
12570                }
12571            }
12572        }
12573    }
12574
12575    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12576        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12577        if (procs == null) {
12578            pw.println("No process found for: " + args[0]);
12579            return;
12580        }
12581
12582        pw.println("Applications Database Info:");
12583
12584        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12585            ProcessRecord r = procs.get(i);
12586            if (r.thread != null) {
12587                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12588                pw.flush();
12589                try {
12590                    TransferPipe tp = new TransferPipe();
12591                    try {
12592                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12593                        tp.go(fd);
12594                    } finally {
12595                        tp.kill();
12596                    }
12597                } catch (IOException e) {
12598                    pw.println("Failure while dumping the app: " + r);
12599                    pw.flush();
12600                } catch (RemoteException e) {
12601                    pw.println("Got a RemoteException while dumping the app " + r);
12602                    pw.flush();
12603                }
12604            }
12605        }
12606    }
12607
12608    final static class MemItem {
12609        final boolean isProc;
12610        final String label;
12611        final String shortLabel;
12612        final long pss;
12613        final int id;
12614        final boolean hasActivities;
12615        ArrayList<MemItem> subitems;
12616
12617        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12618                boolean _hasActivities) {
12619            isProc = true;
12620            label = _label;
12621            shortLabel = _shortLabel;
12622            pss = _pss;
12623            id = _id;
12624            hasActivities = _hasActivities;
12625        }
12626
12627        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12628            isProc = false;
12629            label = _label;
12630            shortLabel = _shortLabel;
12631            pss = _pss;
12632            id = _id;
12633            hasActivities = false;
12634        }
12635    }
12636
12637    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12638            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12639        if (sort && !isCompact) {
12640            Collections.sort(items, new Comparator<MemItem>() {
12641                @Override
12642                public int compare(MemItem lhs, MemItem rhs) {
12643                    if (lhs.pss < rhs.pss) {
12644                        return 1;
12645                    } else if (lhs.pss > rhs.pss) {
12646                        return -1;
12647                    }
12648                    return 0;
12649                }
12650            });
12651        }
12652
12653        for (int i=0; i<items.size(); i++) {
12654            MemItem mi = items.get(i);
12655            if (!isCompact) {
12656                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12657            } else if (mi.isProc) {
12658                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12659                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12660                pw.println(mi.hasActivities ? ",a" : ",e");
12661            } else {
12662                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12663                pw.println(mi.pss);
12664            }
12665            if (mi.subitems != null) {
12666                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12667                        true, isCompact);
12668            }
12669        }
12670    }
12671
12672    // These are in KB.
12673    static final long[] DUMP_MEM_BUCKETS = new long[] {
12674        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12675        120*1024, 160*1024, 200*1024,
12676        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12677        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12678    };
12679
12680    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12681            boolean stackLike) {
12682        int start = label.lastIndexOf('.');
12683        if (start >= 0) start++;
12684        else start = 0;
12685        int end = label.length();
12686        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12687            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12688                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12689                out.append(bucket);
12690                out.append(stackLike ? "MB." : "MB ");
12691                out.append(label, start, end);
12692                return;
12693            }
12694        }
12695        out.append(memKB/1024);
12696        out.append(stackLike ? "MB." : "MB ");
12697        out.append(label, start, end);
12698    }
12699
12700    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12701            ProcessList.NATIVE_ADJ,
12702            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12703            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12704            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12705            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12706            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12707    };
12708    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12709            "Native",
12710            "System", "Persistent", "Foreground",
12711            "Visible", "Perceptible",
12712            "Heavy Weight", "Backup",
12713            "A Services", "Home",
12714            "Previous", "B Services", "Cached"
12715    };
12716    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12717            "native",
12718            "sys", "pers", "fore",
12719            "vis", "percept",
12720            "heavy", "backup",
12721            "servicea", "home",
12722            "prev", "serviceb", "cached"
12723    };
12724
12725    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12726            long realtime, boolean isCheckinRequest, boolean isCompact) {
12727        if (isCheckinRequest || isCompact) {
12728            // short checkin version
12729            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12730        } else {
12731            pw.println("Applications Memory Usage (kB):");
12732            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12733        }
12734    }
12735
12736    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12737            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12738        boolean dumpDetails = false;
12739        boolean dumpFullDetails = false;
12740        boolean dumpDalvik = false;
12741        boolean oomOnly = false;
12742        boolean isCompact = false;
12743        boolean localOnly = false;
12744
12745        int opti = 0;
12746        while (opti < args.length) {
12747            String opt = args[opti];
12748            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12749                break;
12750            }
12751            opti++;
12752            if ("-a".equals(opt)) {
12753                dumpDetails = true;
12754                dumpFullDetails = true;
12755                dumpDalvik = true;
12756            } else if ("-d".equals(opt)) {
12757                dumpDalvik = true;
12758            } else if ("-c".equals(opt)) {
12759                isCompact = true;
12760            } else if ("--oom".equals(opt)) {
12761                oomOnly = true;
12762            } else if ("--local".equals(opt)) {
12763                localOnly = true;
12764            } else if ("-h".equals(opt)) {
12765                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12766                pw.println("  -a: include all available information for each process.");
12767                pw.println("  -d: include dalvik details when dumping process details.");
12768                pw.println("  -c: dump in a compact machine-parseable representation.");
12769                pw.println("  --oom: only show processes organized by oom adj.");
12770                pw.println("  --local: only collect details locally, don't call process.");
12771                pw.println("If [process] is specified it can be the name or ");
12772                pw.println("pid of a specific process to dump.");
12773                return;
12774            } else {
12775                pw.println("Unknown argument: " + opt + "; use -h for help");
12776            }
12777        }
12778
12779        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12780        long uptime = SystemClock.uptimeMillis();
12781        long realtime = SystemClock.elapsedRealtime();
12782        final long[] tmpLong = new long[1];
12783
12784        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12785        if (procs == null) {
12786            // No Java processes.  Maybe they want to print a native process.
12787            if (args != null && args.length > opti
12788                    && args[opti].charAt(0) != '-') {
12789                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12790                        = new ArrayList<ProcessCpuTracker.Stats>();
12791                updateCpuStatsNow();
12792                int findPid = -1;
12793                try {
12794                    findPid = Integer.parseInt(args[opti]);
12795                } catch (NumberFormatException e) {
12796                }
12797                synchronized (mProcessCpuThread) {
12798                    final int N = mProcessCpuTracker.countStats();
12799                    for (int i=0; i<N; i++) {
12800                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12801                        if (st.pid == findPid || (st.baseName != null
12802                                && st.baseName.equals(args[opti]))) {
12803                            nativeProcs.add(st);
12804                        }
12805                    }
12806                }
12807                if (nativeProcs.size() > 0) {
12808                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12809                            isCompact);
12810                    Debug.MemoryInfo mi = null;
12811                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12812                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12813                        final int pid = r.pid;
12814                        if (!isCheckinRequest && dumpDetails) {
12815                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12816                        }
12817                        if (mi == null) {
12818                            mi = new Debug.MemoryInfo();
12819                        }
12820                        if (dumpDetails || (!brief && !oomOnly)) {
12821                            Debug.getMemoryInfo(pid, mi);
12822                        } else {
12823                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12824                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12825                        }
12826                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12827                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12828                        if (isCheckinRequest) {
12829                            pw.println();
12830                        }
12831                    }
12832                    return;
12833                }
12834            }
12835            pw.println("No process found for: " + args[opti]);
12836            return;
12837        }
12838
12839        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12840            dumpDetails = true;
12841        }
12842
12843        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12844
12845        String[] innerArgs = new String[args.length-opti];
12846        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12847
12848        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12849        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12850        long nativePss=0, dalvikPss=0, otherPss=0;
12851        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12852
12853        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12854        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12855                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12856
12857        long totalPss = 0;
12858        long cachedPss = 0;
12859
12860        Debug.MemoryInfo mi = null;
12861        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12862            final ProcessRecord r = procs.get(i);
12863            final IApplicationThread thread;
12864            final int pid;
12865            final int oomAdj;
12866            final boolean hasActivities;
12867            synchronized (this) {
12868                thread = r.thread;
12869                pid = r.pid;
12870                oomAdj = r.getSetAdjWithServices();
12871                hasActivities = r.activities.size() > 0;
12872            }
12873            if (thread != null) {
12874                if (!isCheckinRequest && dumpDetails) {
12875                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12876                }
12877                if (mi == null) {
12878                    mi = new Debug.MemoryInfo();
12879                }
12880                if (dumpDetails || (!brief && !oomOnly)) {
12881                    Debug.getMemoryInfo(pid, mi);
12882                } else {
12883                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12884                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12885                }
12886                if (dumpDetails) {
12887                    if (localOnly) {
12888                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12889                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12890                        if (isCheckinRequest) {
12891                            pw.println();
12892                        }
12893                    } else {
12894                        try {
12895                            pw.flush();
12896                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12897                                    dumpDalvik, innerArgs);
12898                        } catch (RemoteException e) {
12899                            if (!isCheckinRequest) {
12900                                pw.println("Got RemoteException!");
12901                                pw.flush();
12902                            }
12903                        }
12904                    }
12905                }
12906
12907                final long myTotalPss = mi.getTotalPss();
12908                final long myTotalUss = mi.getTotalUss();
12909
12910                synchronized (this) {
12911                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12912                        // Record this for posterity if the process has been stable.
12913                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12914                    }
12915                }
12916
12917                if (!isCheckinRequest && mi != null) {
12918                    totalPss += myTotalPss;
12919                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12920                            (hasActivities ? " / activities)" : ")"),
12921                            r.processName, myTotalPss, pid, hasActivities);
12922                    procMems.add(pssItem);
12923                    procMemsMap.put(pid, pssItem);
12924
12925                    nativePss += mi.nativePss;
12926                    dalvikPss += mi.dalvikPss;
12927                    otherPss += mi.otherPss;
12928                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12929                        long mem = mi.getOtherPss(j);
12930                        miscPss[j] += mem;
12931                        otherPss -= mem;
12932                    }
12933
12934                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12935                        cachedPss += myTotalPss;
12936                    }
12937
12938                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12939                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12940                                || oomIndex == (oomPss.length-1)) {
12941                            oomPss[oomIndex] += myTotalPss;
12942                            if (oomProcs[oomIndex] == null) {
12943                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12944                            }
12945                            oomProcs[oomIndex].add(pssItem);
12946                            break;
12947                        }
12948                    }
12949                }
12950            }
12951        }
12952
12953        long nativeProcTotalPss = 0;
12954
12955        if (!isCheckinRequest && procs.size() > 1) {
12956            // If we are showing aggregations, also look for native processes to
12957            // include so that our aggregations are more accurate.
12958            updateCpuStatsNow();
12959            synchronized (mProcessCpuThread) {
12960                final int N = mProcessCpuTracker.countStats();
12961                for (int i=0; i<N; i++) {
12962                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12963                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12964                        if (mi == null) {
12965                            mi = new Debug.MemoryInfo();
12966                        }
12967                        if (!brief && !oomOnly) {
12968                            Debug.getMemoryInfo(st.pid, mi);
12969                        } else {
12970                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12971                            mi.nativePrivateDirty = (int)tmpLong[0];
12972                        }
12973
12974                        final long myTotalPss = mi.getTotalPss();
12975                        totalPss += myTotalPss;
12976                        nativeProcTotalPss += myTotalPss;
12977
12978                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12979                                st.name, myTotalPss, st.pid, false);
12980                        procMems.add(pssItem);
12981
12982                        nativePss += mi.nativePss;
12983                        dalvikPss += mi.dalvikPss;
12984                        otherPss += mi.otherPss;
12985                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12986                            long mem = mi.getOtherPss(j);
12987                            miscPss[j] += mem;
12988                            otherPss -= mem;
12989                        }
12990                        oomPss[0] += myTotalPss;
12991                        if (oomProcs[0] == null) {
12992                            oomProcs[0] = new ArrayList<MemItem>();
12993                        }
12994                        oomProcs[0].add(pssItem);
12995                    }
12996                }
12997            }
12998
12999            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13000
13001            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13002            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13003            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13004            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13005                String label = Debug.MemoryInfo.getOtherLabel(j);
13006                catMems.add(new MemItem(label, label, miscPss[j], j));
13007            }
13008
13009            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13010            for (int j=0; j<oomPss.length; j++) {
13011                if (oomPss[j] != 0) {
13012                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13013                            : DUMP_MEM_OOM_LABEL[j];
13014                    MemItem item = new MemItem(label, label, oomPss[j],
13015                            DUMP_MEM_OOM_ADJ[j]);
13016                    item.subitems = oomProcs[j];
13017                    oomMems.add(item);
13018                }
13019            }
13020
13021            if (!brief && !oomOnly && !isCompact) {
13022                pw.println();
13023                pw.println("Total PSS by process:");
13024                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13025                pw.println();
13026            }
13027            if (!isCompact) {
13028                pw.println("Total PSS by OOM adjustment:");
13029            }
13030            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13031            if (!brief && !oomOnly) {
13032                PrintWriter out = categoryPw != null ? categoryPw : pw;
13033                if (!isCompact) {
13034                    out.println();
13035                    out.println("Total PSS by category:");
13036                }
13037                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13038            }
13039            if (!isCompact) {
13040                pw.println();
13041            }
13042            MemInfoReader memInfo = new MemInfoReader();
13043            memInfo.readMemInfo();
13044            if (nativeProcTotalPss > 0) {
13045                synchronized (this) {
13046                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13047                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13048                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13049                            nativeProcTotalPss);
13050                }
13051            }
13052            if (!brief) {
13053                if (!isCompact) {
13054                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13055                    pw.print(" kB (status ");
13056                    switch (mLastMemoryLevel) {
13057                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13058                            pw.println("normal)");
13059                            break;
13060                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13061                            pw.println("moderate)");
13062                            break;
13063                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13064                            pw.println("low)");
13065                            break;
13066                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13067                            pw.println("critical)");
13068                            break;
13069                        default:
13070                            pw.print(mLastMemoryLevel);
13071                            pw.println(")");
13072                            break;
13073                    }
13074                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13075                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13076                            pw.print(cachedPss); pw.print(" cached pss + ");
13077                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13078                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13079                } else {
13080                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13081                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13082                            + memInfo.getFreeSizeKb()); pw.print(",");
13083                    pw.println(totalPss - cachedPss);
13084                }
13085            }
13086            if (!isCompact) {
13087                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13088                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13089                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13090                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13091                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13092                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13093                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13094                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13095                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13096                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13097                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13098            }
13099            if (!brief) {
13100                if (memInfo.getZramTotalSizeKb() != 0) {
13101                    if (!isCompact) {
13102                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13103                                pw.print(" kB physical used for ");
13104                                pw.print(memInfo.getSwapTotalSizeKb()
13105                                        - memInfo.getSwapFreeSizeKb());
13106                                pw.print(" kB in swap (");
13107                                pw.print(memInfo.getSwapTotalSizeKb());
13108                                pw.println(" kB total swap)");
13109                    } else {
13110                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13111                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13112                                pw.println(memInfo.getSwapFreeSizeKb());
13113                    }
13114                }
13115                final int[] SINGLE_LONG_FORMAT = new int[] {
13116                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13117                };
13118                long[] longOut = new long[1];
13119                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13120                        SINGLE_LONG_FORMAT, null, longOut, null);
13121                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13122                longOut[0] = 0;
13123                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13124                        SINGLE_LONG_FORMAT, null, longOut, null);
13125                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13126                longOut[0] = 0;
13127                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13128                        SINGLE_LONG_FORMAT, null, longOut, null);
13129                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13130                longOut[0] = 0;
13131                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13132                        SINGLE_LONG_FORMAT, null, longOut, null);
13133                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13134                if (!isCompact) {
13135                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13136                        pw.print("      KSM: "); pw.print(sharing);
13137                                pw.print(" kB saved from shared ");
13138                                pw.print(shared); pw.println(" kB");
13139                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13140                                pw.print(voltile); pw.println(" kB volatile");
13141                    }
13142                    pw.print("   Tuning: ");
13143                    pw.print(ActivityManager.staticGetMemoryClass());
13144                    pw.print(" (large ");
13145                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13146                    pw.print("), oom ");
13147                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13148                    pw.print(" kB");
13149                    pw.print(", restore limit ");
13150                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13151                    pw.print(" kB");
13152                    if (ActivityManager.isLowRamDeviceStatic()) {
13153                        pw.print(" (low-ram)");
13154                    }
13155                    if (ActivityManager.isHighEndGfx()) {
13156                        pw.print(" (high-end-gfx)");
13157                    }
13158                    pw.println();
13159                } else {
13160                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13161                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13162                    pw.println(voltile);
13163                    pw.print("tuning,");
13164                    pw.print(ActivityManager.staticGetMemoryClass());
13165                    pw.print(',');
13166                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13167                    pw.print(',');
13168                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13169                    if (ActivityManager.isLowRamDeviceStatic()) {
13170                        pw.print(",low-ram");
13171                    }
13172                    if (ActivityManager.isHighEndGfx()) {
13173                        pw.print(",high-end-gfx");
13174                    }
13175                    pw.println();
13176                }
13177            }
13178        }
13179    }
13180
13181    /**
13182     * Searches array of arguments for the specified string
13183     * @param args array of argument strings
13184     * @param value value to search for
13185     * @return true if the value is contained in the array
13186     */
13187    private static boolean scanArgs(String[] args, String value) {
13188        if (args != null) {
13189            for (String arg : args) {
13190                if (value.equals(arg)) {
13191                    return true;
13192                }
13193            }
13194        }
13195        return false;
13196    }
13197
13198    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13199            ContentProviderRecord cpr, boolean always) {
13200        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13201
13202        if (!inLaunching || always) {
13203            synchronized (cpr) {
13204                cpr.launchingApp = null;
13205                cpr.notifyAll();
13206            }
13207            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13208            String names[] = cpr.info.authority.split(";");
13209            for (int j = 0; j < names.length; j++) {
13210                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13211            }
13212        }
13213
13214        for (int i=0; i<cpr.connections.size(); i++) {
13215            ContentProviderConnection conn = cpr.connections.get(i);
13216            if (conn.waiting) {
13217                // If this connection is waiting for the provider, then we don't
13218                // need to mess with its process unless we are always removing
13219                // or for some reason the provider is not currently launching.
13220                if (inLaunching && !always) {
13221                    continue;
13222                }
13223            }
13224            ProcessRecord capp = conn.client;
13225            conn.dead = true;
13226            if (conn.stableCount > 0) {
13227                if (!capp.persistent && capp.thread != null
13228                        && capp.pid != 0
13229                        && capp.pid != MY_PID) {
13230                    killUnneededProcessLocked(capp, "depends on provider "
13231                            + cpr.name.flattenToShortString()
13232                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13233                }
13234            } else if (capp.thread != null && conn.provider.provider != null) {
13235                try {
13236                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13237                } catch (RemoteException e) {
13238                }
13239                // In the protocol here, we don't expect the client to correctly
13240                // clean up this connection, we'll just remove it.
13241                cpr.connections.remove(i);
13242                conn.client.conProviders.remove(conn);
13243            }
13244        }
13245
13246        if (inLaunching && always) {
13247            mLaunchingProviders.remove(cpr);
13248        }
13249        return inLaunching;
13250    }
13251
13252    /**
13253     * Main code for cleaning up a process when it has gone away.  This is
13254     * called both as a result of the process dying, or directly when stopping
13255     * a process when running in single process mode.
13256     */
13257    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13258            boolean restarting, boolean allowRestart, int index) {
13259        if (index >= 0) {
13260            removeLruProcessLocked(app);
13261            ProcessList.remove(app.pid);
13262        }
13263
13264        mProcessesToGc.remove(app);
13265        mPendingPssProcesses.remove(app);
13266
13267        // Dismiss any open dialogs.
13268        if (app.crashDialog != null && !app.forceCrashReport) {
13269            app.crashDialog.dismiss();
13270            app.crashDialog = null;
13271        }
13272        if (app.anrDialog != null) {
13273            app.anrDialog.dismiss();
13274            app.anrDialog = null;
13275        }
13276        if (app.waitDialog != null) {
13277            app.waitDialog.dismiss();
13278            app.waitDialog = null;
13279        }
13280
13281        app.crashing = false;
13282        app.notResponding = false;
13283
13284        app.resetPackageList(mProcessStats);
13285        app.unlinkDeathRecipient();
13286        app.makeInactive(mProcessStats);
13287        app.waitingToKill = null;
13288        app.forcingToForeground = null;
13289        updateProcessForegroundLocked(app, false, false);
13290        app.foregroundActivities = false;
13291        app.hasShownUi = false;
13292        app.treatLikeActivity = false;
13293        app.hasAboveClient = false;
13294        app.hasClientActivities = false;
13295
13296        mServices.killServicesLocked(app, allowRestart);
13297
13298        boolean restart = false;
13299
13300        // Remove published content providers.
13301        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13302            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13303            final boolean always = app.bad || !allowRestart;
13304            if (removeDyingProviderLocked(app, cpr, always) || always) {
13305                // We left the provider in the launching list, need to
13306                // restart it.
13307                restart = true;
13308            }
13309
13310            cpr.provider = null;
13311            cpr.proc = null;
13312        }
13313        app.pubProviders.clear();
13314
13315        // Take care of any launching providers waiting for this process.
13316        if (checkAppInLaunchingProvidersLocked(app, false)) {
13317            restart = true;
13318        }
13319
13320        // Unregister from connected content providers.
13321        if (!app.conProviders.isEmpty()) {
13322            for (int i=0; i<app.conProviders.size(); i++) {
13323                ContentProviderConnection conn = app.conProviders.get(i);
13324                conn.provider.connections.remove(conn);
13325            }
13326            app.conProviders.clear();
13327        }
13328
13329        // At this point there may be remaining entries in mLaunchingProviders
13330        // where we were the only one waiting, so they are no longer of use.
13331        // Look for these and clean up if found.
13332        // XXX Commented out for now.  Trying to figure out a way to reproduce
13333        // the actual situation to identify what is actually going on.
13334        if (false) {
13335            for (int i=0; i<mLaunchingProviders.size(); i++) {
13336                ContentProviderRecord cpr = (ContentProviderRecord)
13337                        mLaunchingProviders.get(i);
13338                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13339                    synchronized (cpr) {
13340                        cpr.launchingApp = null;
13341                        cpr.notifyAll();
13342                    }
13343                }
13344            }
13345        }
13346
13347        skipCurrentReceiverLocked(app);
13348
13349        // Unregister any receivers.
13350        for (int i=app.receivers.size()-1; i>=0; i--) {
13351            removeReceiverLocked(app.receivers.valueAt(i));
13352        }
13353        app.receivers.clear();
13354
13355        // If the app is undergoing backup, tell the backup manager about it
13356        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13357            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13358                    + mBackupTarget.appInfo + " died during backup");
13359            try {
13360                IBackupManager bm = IBackupManager.Stub.asInterface(
13361                        ServiceManager.getService(Context.BACKUP_SERVICE));
13362                bm.agentDisconnected(app.info.packageName);
13363            } catch (RemoteException e) {
13364                // can't happen; backup manager is local
13365            }
13366        }
13367
13368        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13369            ProcessChangeItem item = mPendingProcessChanges.get(i);
13370            if (item.pid == app.pid) {
13371                mPendingProcessChanges.remove(i);
13372                mAvailProcessChanges.add(item);
13373            }
13374        }
13375        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13376
13377        // If the caller is restarting this app, then leave it in its
13378        // current lists and let the caller take care of it.
13379        if (restarting) {
13380            return;
13381        }
13382
13383        if (!app.persistent || app.isolated) {
13384            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13385                    "Removing non-persistent process during cleanup: " + app);
13386            mProcessNames.remove(app.processName, app.uid);
13387            mIsolatedProcesses.remove(app.uid);
13388            if (mHeavyWeightProcess == app) {
13389                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13390                        mHeavyWeightProcess.userId, 0));
13391                mHeavyWeightProcess = null;
13392            }
13393        } else if (!app.removed) {
13394            // This app is persistent, so we need to keep its record around.
13395            // If it is not already on the pending app list, add it there
13396            // and start a new process for it.
13397            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13398                mPersistentStartingProcesses.add(app);
13399                restart = true;
13400            }
13401        }
13402        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13403                "Clean-up removing on hold: " + app);
13404        mProcessesOnHold.remove(app);
13405
13406        if (app == mHomeProcess) {
13407            mHomeProcess = null;
13408        }
13409        if (app == mPreviousProcess) {
13410            mPreviousProcess = null;
13411        }
13412
13413        if (restart && !app.isolated) {
13414            // We have components that still need to be running in the
13415            // process, so re-launch it.
13416            mProcessNames.put(app.processName, app.uid, app);
13417            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13418        } else if (app.pid > 0 && app.pid != MY_PID) {
13419            // Goodbye!
13420            boolean removed;
13421            synchronized (mPidsSelfLocked) {
13422                mPidsSelfLocked.remove(app.pid);
13423                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13424            }
13425            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13426            if (app.isolated) {
13427                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13428            }
13429            app.setPid(0);
13430        }
13431    }
13432
13433    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13434        // Look through the content providers we are waiting to have launched,
13435        // and if any run in this process then either schedule a restart of
13436        // the process or kill the client waiting for it if this process has
13437        // gone bad.
13438        int NL = mLaunchingProviders.size();
13439        boolean restart = false;
13440        for (int i=0; i<NL; i++) {
13441            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13442            if (cpr.launchingApp == app) {
13443                if (!alwaysBad && !app.bad) {
13444                    restart = true;
13445                } else {
13446                    removeDyingProviderLocked(app, cpr, true);
13447                    // cpr should have been removed from mLaunchingProviders
13448                    NL = mLaunchingProviders.size();
13449                    i--;
13450                }
13451            }
13452        }
13453        return restart;
13454    }
13455
13456    // =========================================================
13457    // SERVICES
13458    // =========================================================
13459
13460    @Override
13461    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13462            int flags) {
13463        enforceNotIsolatedCaller("getServices");
13464        synchronized (this) {
13465            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13466        }
13467    }
13468
13469    @Override
13470    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13471        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13472        synchronized (this) {
13473            return mServices.getRunningServiceControlPanelLocked(name);
13474        }
13475    }
13476
13477    @Override
13478    public ComponentName startService(IApplicationThread caller, Intent service,
13479            String resolvedType, int userId) {
13480        enforceNotIsolatedCaller("startService");
13481        // Refuse possible leaked file descriptors
13482        if (service != null && service.hasFileDescriptors() == true) {
13483            throw new IllegalArgumentException("File descriptors passed in Intent");
13484        }
13485
13486        if (DEBUG_SERVICE)
13487            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13488        synchronized(this) {
13489            final int callingPid = Binder.getCallingPid();
13490            final int callingUid = Binder.getCallingUid();
13491            final long origId = Binder.clearCallingIdentity();
13492            ComponentName res = mServices.startServiceLocked(caller, service,
13493                    resolvedType, callingPid, callingUid, userId);
13494            Binder.restoreCallingIdentity(origId);
13495            return res;
13496        }
13497    }
13498
13499    ComponentName startServiceInPackage(int uid,
13500            Intent service, String resolvedType, int userId) {
13501        synchronized(this) {
13502            if (DEBUG_SERVICE)
13503                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13504            final long origId = Binder.clearCallingIdentity();
13505            ComponentName res = mServices.startServiceLocked(null, service,
13506                    resolvedType, -1, uid, userId);
13507            Binder.restoreCallingIdentity(origId);
13508            return res;
13509        }
13510    }
13511
13512    @Override
13513    public int stopService(IApplicationThread caller, Intent service,
13514            String resolvedType, int userId) {
13515        enforceNotIsolatedCaller("stopService");
13516        // Refuse possible leaked file descriptors
13517        if (service != null && service.hasFileDescriptors() == true) {
13518            throw new IllegalArgumentException("File descriptors passed in Intent");
13519        }
13520
13521        synchronized(this) {
13522            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13523        }
13524    }
13525
13526    @Override
13527    public IBinder peekService(Intent service, String resolvedType) {
13528        enforceNotIsolatedCaller("peekService");
13529        // Refuse possible leaked file descriptors
13530        if (service != null && service.hasFileDescriptors() == true) {
13531            throw new IllegalArgumentException("File descriptors passed in Intent");
13532        }
13533        synchronized(this) {
13534            return mServices.peekServiceLocked(service, resolvedType);
13535        }
13536    }
13537
13538    @Override
13539    public boolean stopServiceToken(ComponentName className, IBinder token,
13540            int startId) {
13541        synchronized(this) {
13542            return mServices.stopServiceTokenLocked(className, token, startId);
13543        }
13544    }
13545
13546    @Override
13547    public void setServiceForeground(ComponentName className, IBinder token,
13548            int id, Notification notification, boolean removeNotification) {
13549        synchronized(this) {
13550            mServices.setServiceForegroundLocked(className, token, id, notification,
13551                    removeNotification);
13552        }
13553    }
13554
13555    @Override
13556    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13557            boolean requireFull, String name, String callerPackage) {
13558        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13559                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13560    }
13561
13562    int unsafeConvertIncomingUser(int userId) {
13563        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13564                ? mCurrentUserId : userId;
13565    }
13566
13567    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13568            int allowMode, String name, String callerPackage) {
13569        final int callingUserId = UserHandle.getUserId(callingUid);
13570        if (callingUserId == userId) {
13571            return userId;
13572        }
13573
13574        // Note that we may be accessing mCurrentUserId outside of a lock...
13575        // shouldn't be a big deal, if this is being called outside
13576        // of a locked context there is intrinsically a race with
13577        // the value the caller will receive and someone else changing it.
13578        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13579        // we will switch to the calling user if access to the current user fails.
13580        int targetUserId = unsafeConvertIncomingUser(userId);
13581
13582        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13583            final boolean allow;
13584            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13585                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13586                // If the caller has this permission, they always pass go.  And collect $200.
13587                allow = true;
13588            } else if (allowMode == ALLOW_FULL_ONLY) {
13589                // We require full access, sucks to be you.
13590                allow = false;
13591            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13592                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13593                // If the caller does not have either permission, they are always doomed.
13594                allow = false;
13595            } else if (allowMode == ALLOW_NON_FULL) {
13596                // We are blanket allowing non-full access, you lucky caller!
13597                allow = true;
13598            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13599                // We may or may not allow this depending on whether the two users are
13600                // in the same profile.
13601                synchronized (mUserProfileGroupIdsSelfLocked) {
13602                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13603                            UserInfo.NO_PROFILE_GROUP_ID);
13604                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13605                            UserInfo.NO_PROFILE_GROUP_ID);
13606                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13607                            && callingProfile == targetProfile;
13608                }
13609            } else {
13610                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13611            }
13612            if (!allow) {
13613                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13614                    // In this case, they would like to just execute as their
13615                    // owner user instead of failing.
13616                    targetUserId = callingUserId;
13617                } else {
13618                    StringBuilder builder = new StringBuilder(128);
13619                    builder.append("Permission Denial: ");
13620                    builder.append(name);
13621                    if (callerPackage != null) {
13622                        builder.append(" from ");
13623                        builder.append(callerPackage);
13624                    }
13625                    builder.append(" asks to run as user ");
13626                    builder.append(userId);
13627                    builder.append(" but is calling from user ");
13628                    builder.append(UserHandle.getUserId(callingUid));
13629                    builder.append("; this requires ");
13630                    builder.append(INTERACT_ACROSS_USERS_FULL);
13631                    if (allowMode != ALLOW_FULL_ONLY) {
13632                        builder.append(" or ");
13633                        builder.append(INTERACT_ACROSS_USERS);
13634                    }
13635                    String msg = builder.toString();
13636                    Slog.w(TAG, msg);
13637                    throw new SecurityException(msg);
13638                }
13639            }
13640        }
13641        if (!allowAll && targetUserId < 0) {
13642            throw new IllegalArgumentException(
13643                    "Call does not support special user #" + targetUserId);
13644        }
13645        return targetUserId;
13646    }
13647
13648    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13649            String className, int flags) {
13650        boolean result = false;
13651        // For apps that don't have pre-defined UIDs, check for permission
13652        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13653            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13654                if (ActivityManager.checkUidPermission(
13655                        INTERACT_ACROSS_USERS,
13656                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13657                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13658                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13659                            + " requests FLAG_SINGLE_USER, but app does not hold "
13660                            + INTERACT_ACROSS_USERS;
13661                    Slog.w(TAG, msg);
13662                    throw new SecurityException(msg);
13663                }
13664                // Permission passed
13665                result = true;
13666            }
13667        } else if ("system".equals(componentProcessName)) {
13668            result = true;
13669        } else {
13670            // App with pre-defined UID, check if it's a persistent app
13671            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13672        }
13673        if (DEBUG_MU) {
13674            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13675                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13676        }
13677        return result;
13678    }
13679
13680    /**
13681     * Checks to see if the caller is in the same app as the singleton
13682     * component, or the component is in a special app. It allows special apps
13683     * to export singleton components but prevents exporting singleton
13684     * components for regular apps.
13685     */
13686    boolean isValidSingletonCall(int callingUid, int componentUid) {
13687        int componentAppId = UserHandle.getAppId(componentUid);
13688        return UserHandle.isSameApp(callingUid, componentUid)
13689                || componentAppId == Process.SYSTEM_UID
13690                || componentAppId == Process.PHONE_UID
13691                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13692                        == PackageManager.PERMISSION_GRANTED;
13693    }
13694
13695    public int bindService(IApplicationThread caller, IBinder token,
13696            Intent service, String resolvedType,
13697            IServiceConnection connection, int flags, int userId) {
13698        enforceNotIsolatedCaller("bindService");
13699        // Refuse possible leaked file descriptors
13700        if (service != null && service.hasFileDescriptors() == true) {
13701            throw new IllegalArgumentException("File descriptors passed in Intent");
13702        }
13703
13704        synchronized(this) {
13705            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13706                    connection, flags, userId);
13707        }
13708    }
13709
13710    public boolean unbindService(IServiceConnection connection) {
13711        synchronized (this) {
13712            return mServices.unbindServiceLocked(connection);
13713        }
13714    }
13715
13716    public void publishService(IBinder token, Intent intent, IBinder service) {
13717        // Refuse possible leaked file descriptors
13718        if (intent != null && intent.hasFileDescriptors() == true) {
13719            throw new IllegalArgumentException("File descriptors passed in Intent");
13720        }
13721
13722        synchronized(this) {
13723            if (!(token instanceof ServiceRecord)) {
13724                throw new IllegalArgumentException("Invalid service token");
13725            }
13726            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13727        }
13728    }
13729
13730    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13731        // Refuse possible leaked file descriptors
13732        if (intent != null && intent.hasFileDescriptors() == true) {
13733            throw new IllegalArgumentException("File descriptors passed in Intent");
13734        }
13735
13736        synchronized(this) {
13737            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13738        }
13739    }
13740
13741    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13742        synchronized(this) {
13743            if (!(token instanceof ServiceRecord)) {
13744                throw new IllegalArgumentException("Invalid service token");
13745            }
13746            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13747        }
13748    }
13749
13750    // =========================================================
13751    // BACKUP AND RESTORE
13752    // =========================================================
13753
13754    // Cause the target app to be launched if necessary and its backup agent
13755    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13756    // activity manager to announce its creation.
13757    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13758        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13759        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13760
13761        synchronized(this) {
13762            // !!! TODO: currently no check here that we're already bound
13763            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13764            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13765            synchronized (stats) {
13766                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13767            }
13768
13769            // Backup agent is now in use, its package can't be stopped.
13770            try {
13771                AppGlobals.getPackageManager().setPackageStoppedState(
13772                        app.packageName, false, UserHandle.getUserId(app.uid));
13773            } catch (RemoteException e) {
13774            } catch (IllegalArgumentException e) {
13775                Slog.w(TAG, "Failed trying to unstop package "
13776                        + app.packageName + ": " + e);
13777            }
13778
13779            BackupRecord r = new BackupRecord(ss, app, backupMode);
13780            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13781                    ? new ComponentName(app.packageName, app.backupAgentName)
13782                    : new ComponentName("android", "FullBackupAgent");
13783            // startProcessLocked() returns existing proc's record if it's already running
13784            ProcessRecord proc = startProcessLocked(app.processName, app,
13785                    false, 0, "backup", hostingName, false, false, false);
13786            if (proc == null) {
13787                Slog.e(TAG, "Unable to start backup agent process " + r);
13788                return false;
13789            }
13790
13791            r.app = proc;
13792            mBackupTarget = r;
13793            mBackupAppName = app.packageName;
13794
13795            // Try not to kill the process during backup
13796            updateOomAdjLocked(proc);
13797
13798            // If the process is already attached, schedule the creation of the backup agent now.
13799            // If it is not yet live, this will be done when it attaches to the framework.
13800            if (proc.thread != null) {
13801                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13802                try {
13803                    proc.thread.scheduleCreateBackupAgent(app,
13804                            compatibilityInfoForPackageLocked(app), backupMode);
13805                } catch (RemoteException e) {
13806                    // Will time out on the backup manager side
13807                }
13808            } else {
13809                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13810            }
13811            // Invariants: at this point, the target app process exists and the application
13812            // is either already running or in the process of coming up.  mBackupTarget and
13813            // mBackupAppName describe the app, so that when it binds back to the AM we
13814            // know that it's scheduled for a backup-agent operation.
13815        }
13816
13817        return true;
13818    }
13819
13820    @Override
13821    public void clearPendingBackup() {
13822        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13823        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13824
13825        synchronized (this) {
13826            mBackupTarget = null;
13827            mBackupAppName = null;
13828        }
13829    }
13830
13831    // A backup agent has just come up
13832    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13833        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13834                + " = " + agent);
13835
13836        synchronized(this) {
13837            if (!agentPackageName.equals(mBackupAppName)) {
13838                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13839                return;
13840            }
13841        }
13842
13843        long oldIdent = Binder.clearCallingIdentity();
13844        try {
13845            IBackupManager bm = IBackupManager.Stub.asInterface(
13846                    ServiceManager.getService(Context.BACKUP_SERVICE));
13847            bm.agentConnected(agentPackageName, agent);
13848        } catch (RemoteException e) {
13849            // can't happen; the backup manager service is local
13850        } catch (Exception e) {
13851            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13852            e.printStackTrace();
13853        } finally {
13854            Binder.restoreCallingIdentity(oldIdent);
13855        }
13856    }
13857
13858    // done with this agent
13859    public void unbindBackupAgent(ApplicationInfo appInfo) {
13860        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13861        if (appInfo == null) {
13862            Slog.w(TAG, "unbind backup agent for null app");
13863            return;
13864        }
13865
13866        synchronized(this) {
13867            try {
13868                if (mBackupAppName == null) {
13869                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13870                    return;
13871                }
13872
13873                if (!mBackupAppName.equals(appInfo.packageName)) {
13874                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13875                    return;
13876                }
13877
13878                // Not backing this app up any more; reset its OOM adjustment
13879                final ProcessRecord proc = mBackupTarget.app;
13880                updateOomAdjLocked(proc);
13881
13882                // If the app crashed during backup, 'thread' will be null here
13883                if (proc.thread != null) {
13884                    try {
13885                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13886                                compatibilityInfoForPackageLocked(appInfo));
13887                    } catch (Exception e) {
13888                        Slog.e(TAG, "Exception when unbinding backup agent:");
13889                        e.printStackTrace();
13890                    }
13891                }
13892            } finally {
13893                mBackupTarget = null;
13894                mBackupAppName = null;
13895            }
13896        }
13897    }
13898    // =========================================================
13899    // BROADCASTS
13900    // =========================================================
13901
13902    private final List getStickiesLocked(String action, IntentFilter filter,
13903            List cur, int userId) {
13904        final ContentResolver resolver = mContext.getContentResolver();
13905        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13906        if (stickies == null) {
13907            return cur;
13908        }
13909        final ArrayList<Intent> list = stickies.get(action);
13910        if (list == null) {
13911            return cur;
13912        }
13913        int N = list.size();
13914        for (int i=0; i<N; i++) {
13915            Intent intent = list.get(i);
13916            if (filter.match(resolver, intent, true, TAG) >= 0) {
13917                if (cur == null) {
13918                    cur = new ArrayList<Intent>();
13919                }
13920                cur.add(intent);
13921            }
13922        }
13923        return cur;
13924    }
13925
13926    boolean isPendingBroadcastProcessLocked(int pid) {
13927        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13928                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13929    }
13930
13931    void skipPendingBroadcastLocked(int pid) {
13932            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13933            for (BroadcastQueue queue : mBroadcastQueues) {
13934                queue.skipPendingBroadcastLocked(pid);
13935            }
13936    }
13937
13938    // The app just attached; send any pending broadcasts that it should receive
13939    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13940        boolean didSomething = false;
13941        for (BroadcastQueue queue : mBroadcastQueues) {
13942            didSomething |= queue.sendPendingBroadcastsLocked(app);
13943        }
13944        return didSomething;
13945    }
13946
13947    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13948            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13949        enforceNotIsolatedCaller("registerReceiver");
13950        int callingUid;
13951        int callingPid;
13952        synchronized(this) {
13953            ProcessRecord callerApp = null;
13954            if (caller != null) {
13955                callerApp = getRecordForAppLocked(caller);
13956                if (callerApp == null) {
13957                    throw new SecurityException(
13958                            "Unable to find app for caller " + caller
13959                            + " (pid=" + Binder.getCallingPid()
13960                            + ") when registering receiver " + receiver);
13961                }
13962                if (callerApp.info.uid != Process.SYSTEM_UID &&
13963                        !callerApp.pkgList.containsKey(callerPackage) &&
13964                        !"android".equals(callerPackage)) {
13965                    throw new SecurityException("Given caller package " + callerPackage
13966                            + " is not running in process " + callerApp);
13967                }
13968                callingUid = callerApp.info.uid;
13969                callingPid = callerApp.pid;
13970            } else {
13971                callerPackage = null;
13972                callingUid = Binder.getCallingUid();
13973                callingPid = Binder.getCallingPid();
13974            }
13975
13976            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13977                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
13978
13979            List allSticky = null;
13980
13981            // Look for any matching sticky broadcasts...
13982            Iterator actions = filter.actionsIterator();
13983            if (actions != null) {
13984                while (actions.hasNext()) {
13985                    String action = (String)actions.next();
13986                    allSticky = getStickiesLocked(action, filter, allSticky,
13987                            UserHandle.USER_ALL);
13988                    allSticky = getStickiesLocked(action, filter, allSticky,
13989                            UserHandle.getUserId(callingUid));
13990                }
13991            } else {
13992                allSticky = getStickiesLocked(null, filter, allSticky,
13993                        UserHandle.USER_ALL);
13994                allSticky = getStickiesLocked(null, filter, allSticky,
13995                        UserHandle.getUserId(callingUid));
13996            }
13997
13998            // The first sticky in the list is returned directly back to
13999            // the client.
14000            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14001
14002            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14003                    + ": " + sticky);
14004
14005            if (receiver == null) {
14006                return sticky;
14007            }
14008
14009            ReceiverList rl
14010                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14011            if (rl == null) {
14012                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14013                        userId, receiver);
14014                if (rl.app != null) {
14015                    rl.app.receivers.add(rl);
14016                } else {
14017                    try {
14018                        receiver.asBinder().linkToDeath(rl, 0);
14019                    } catch (RemoteException e) {
14020                        return sticky;
14021                    }
14022                    rl.linkedToDeath = true;
14023                }
14024                mRegisteredReceivers.put(receiver.asBinder(), rl);
14025            } else if (rl.uid != callingUid) {
14026                throw new IllegalArgumentException(
14027                        "Receiver requested to register for uid " + callingUid
14028                        + " was previously registered for uid " + rl.uid);
14029            } else if (rl.pid != callingPid) {
14030                throw new IllegalArgumentException(
14031                        "Receiver requested to register for pid " + callingPid
14032                        + " was previously registered for pid " + rl.pid);
14033            } else if (rl.userId != userId) {
14034                throw new IllegalArgumentException(
14035                        "Receiver requested to register for user " + userId
14036                        + " was previously registered for user " + rl.userId);
14037            }
14038            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14039                    permission, callingUid, userId);
14040            rl.add(bf);
14041            if (!bf.debugCheck()) {
14042                Slog.w(TAG, "==> For Dynamic broadast");
14043            }
14044            mReceiverResolver.addFilter(bf);
14045
14046            // Enqueue broadcasts for all existing stickies that match
14047            // this filter.
14048            if (allSticky != null) {
14049                ArrayList receivers = new ArrayList();
14050                receivers.add(bf);
14051
14052                int N = allSticky.size();
14053                for (int i=0; i<N; i++) {
14054                    Intent intent = (Intent)allSticky.get(i);
14055                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14056                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14057                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14058                            null, null, false, true, true, -1);
14059                    queue.enqueueParallelBroadcastLocked(r);
14060                    queue.scheduleBroadcastsLocked();
14061                }
14062            }
14063
14064            return sticky;
14065        }
14066    }
14067
14068    public void unregisterReceiver(IIntentReceiver receiver) {
14069        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14070
14071        final long origId = Binder.clearCallingIdentity();
14072        try {
14073            boolean doTrim = false;
14074
14075            synchronized(this) {
14076                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14077                if (rl != null) {
14078                    if (rl.curBroadcast != null) {
14079                        BroadcastRecord r = rl.curBroadcast;
14080                        final boolean doNext = finishReceiverLocked(
14081                                receiver.asBinder(), r.resultCode, r.resultData,
14082                                r.resultExtras, r.resultAbort);
14083                        if (doNext) {
14084                            doTrim = true;
14085                            r.queue.processNextBroadcast(false);
14086                        }
14087                    }
14088
14089                    if (rl.app != null) {
14090                        rl.app.receivers.remove(rl);
14091                    }
14092                    removeReceiverLocked(rl);
14093                    if (rl.linkedToDeath) {
14094                        rl.linkedToDeath = false;
14095                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14096                    }
14097                }
14098            }
14099
14100            // If we actually concluded any broadcasts, we might now be able
14101            // to trim the recipients' apps from our working set
14102            if (doTrim) {
14103                trimApplications();
14104                return;
14105            }
14106
14107        } finally {
14108            Binder.restoreCallingIdentity(origId);
14109        }
14110    }
14111
14112    void removeReceiverLocked(ReceiverList rl) {
14113        mRegisteredReceivers.remove(rl.receiver.asBinder());
14114        int N = rl.size();
14115        for (int i=0; i<N; i++) {
14116            mReceiverResolver.removeFilter(rl.get(i));
14117        }
14118    }
14119
14120    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14121        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14122            ProcessRecord r = mLruProcesses.get(i);
14123            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14124                try {
14125                    r.thread.dispatchPackageBroadcast(cmd, packages);
14126                } catch (RemoteException ex) {
14127                }
14128            }
14129        }
14130    }
14131
14132    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14133            int[] users) {
14134        List<ResolveInfo> receivers = null;
14135        try {
14136            HashSet<ComponentName> singleUserReceivers = null;
14137            boolean scannedFirstReceivers = false;
14138            for (int user : users) {
14139                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14140                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14141                if (user != 0 && newReceivers != null) {
14142                    // If this is not the primary user, we need to check for
14143                    // any receivers that should be filtered out.
14144                    for (int i=0; i<newReceivers.size(); i++) {
14145                        ResolveInfo ri = newReceivers.get(i);
14146                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14147                            newReceivers.remove(i);
14148                            i--;
14149                        }
14150                    }
14151                }
14152                if (newReceivers != null && newReceivers.size() == 0) {
14153                    newReceivers = null;
14154                }
14155                if (receivers == null) {
14156                    receivers = newReceivers;
14157                } else if (newReceivers != null) {
14158                    // We need to concatenate the additional receivers
14159                    // found with what we have do far.  This would be easy,
14160                    // but we also need to de-dup any receivers that are
14161                    // singleUser.
14162                    if (!scannedFirstReceivers) {
14163                        // Collect any single user receivers we had already retrieved.
14164                        scannedFirstReceivers = true;
14165                        for (int i=0; i<receivers.size(); i++) {
14166                            ResolveInfo ri = receivers.get(i);
14167                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14168                                ComponentName cn = new ComponentName(
14169                                        ri.activityInfo.packageName, ri.activityInfo.name);
14170                                if (singleUserReceivers == null) {
14171                                    singleUserReceivers = new HashSet<ComponentName>();
14172                                }
14173                                singleUserReceivers.add(cn);
14174                            }
14175                        }
14176                    }
14177                    // Add the new results to the existing results, tracking
14178                    // and de-dupping single user receivers.
14179                    for (int i=0; i<newReceivers.size(); i++) {
14180                        ResolveInfo ri = newReceivers.get(i);
14181                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14182                            ComponentName cn = new ComponentName(
14183                                    ri.activityInfo.packageName, ri.activityInfo.name);
14184                            if (singleUserReceivers == null) {
14185                                singleUserReceivers = new HashSet<ComponentName>();
14186                            }
14187                            if (!singleUserReceivers.contains(cn)) {
14188                                singleUserReceivers.add(cn);
14189                                receivers.add(ri);
14190                            }
14191                        } else {
14192                            receivers.add(ri);
14193                        }
14194                    }
14195                }
14196            }
14197        } catch (RemoteException ex) {
14198            // pm is in same process, this will never happen.
14199        }
14200        return receivers;
14201    }
14202
14203    private final int broadcastIntentLocked(ProcessRecord callerApp,
14204            String callerPackage, Intent intent, String resolvedType,
14205            IIntentReceiver resultTo, int resultCode, String resultData,
14206            Bundle map, String requiredPermission, int appOp,
14207            boolean ordered, boolean sticky, int callingPid, int callingUid,
14208            int userId) {
14209        intent = new Intent(intent);
14210
14211        // By default broadcasts do not go to stopped apps.
14212        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14213
14214        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14215            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14216            + " ordered=" + ordered + " userid=" + userId);
14217        if ((resultTo != null) && !ordered) {
14218            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14219        }
14220
14221        userId = handleIncomingUser(callingPid, callingUid, userId,
14222                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14223
14224        // Make sure that the user who is receiving this broadcast is started.
14225        // If not, we will just skip it.
14226
14227
14228        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14229            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14230                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14231                Slog.w(TAG, "Skipping broadcast of " + intent
14232                        + ": user " + userId + " is stopped");
14233                return ActivityManager.BROADCAST_SUCCESS;
14234            }
14235        }
14236
14237        /*
14238         * Prevent non-system code (defined here to be non-persistent
14239         * processes) from sending protected broadcasts.
14240         */
14241        int callingAppId = UserHandle.getAppId(callingUid);
14242        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14243            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14244            || callingAppId == Process.NFC_UID || callingUid == 0) {
14245            // Always okay.
14246        } else if (callerApp == null || !callerApp.persistent) {
14247            try {
14248                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14249                        intent.getAction())) {
14250                    String msg = "Permission Denial: not allowed to send broadcast "
14251                            + intent.getAction() + " from pid="
14252                            + callingPid + ", uid=" + callingUid;
14253                    Slog.w(TAG, msg);
14254                    throw new SecurityException(msg);
14255                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14256                    // Special case for compatibility: we don't want apps to send this,
14257                    // but historically it has not been protected and apps may be using it
14258                    // to poke their own app widget.  So, instead of making it protected,
14259                    // just limit it to the caller.
14260                    if (callerApp == null) {
14261                        String msg = "Permission Denial: not allowed to send broadcast "
14262                                + intent.getAction() + " from unknown caller.";
14263                        Slog.w(TAG, msg);
14264                        throw new SecurityException(msg);
14265                    } else if (intent.getComponent() != null) {
14266                        // They are good enough to send to an explicit component...  verify
14267                        // it is being sent to the calling app.
14268                        if (!intent.getComponent().getPackageName().equals(
14269                                callerApp.info.packageName)) {
14270                            String msg = "Permission Denial: not allowed to send broadcast "
14271                                    + intent.getAction() + " to "
14272                                    + intent.getComponent().getPackageName() + " from "
14273                                    + callerApp.info.packageName;
14274                            Slog.w(TAG, msg);
14275                            throw new SecurityException(msg);
14276                        }
14277                    } else {
14278                        // Limit broadcast to their own package.
14279                        intent.setPackage(callerApp.info.packageName);
14280                    }
14281                }
14282            } catch (RemoteException e) {
14283                Slog.w(TAG, "Remote exception", e);
14284                return ActivityManager.BROADCAST_SUCCESS;
14285            }
14286        }
14287
14288        // Handle special intents: if this broadcast is from the package
14289        // manager about a package being removed, we need to remove all of
14290        // its activities from the history stack.
14291        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14292                intent.getAction());
14293        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14294                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14295                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14296                || uidRemoved) {
14297            if (checkComponentPermission(
14298                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14299                    callingPid, callingUid, -1, true)
14300                    == PackageManager.PERMISSION_GRANTED) {
14301                if (uidRemoved) {
14302                    final Bundle intentExtras = intent.getExtras();
14303                    final int uid = intentExtras != null
14304                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14305                    if (uid >= 0) {
14306                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14307                        synchronized (bs) {
14308                            bs.removeUidStatsLocked(uid);
14309                        }
14310                        mAppOpsService.uidRemoved(uid);
14311                    }
14312                } else {
14313                    // If resources are unavailable just force stop all
14314                    // those packages and flush the attribute cache as well.
14315                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14316                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14317                        if (list != null && (list.length > 0)) {
14318                            for (String pkg : list) {
14319                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14320                                        "storage unmount");
14321                            }
14322                            sendPackageBroadcastLocked(
14323                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14324                        }
14325                    } else {
14326                        Uri data = intent.getData();
14327                        String ssp;
14328                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14329                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14330                                    intent.getAction());
14331                            boolean fullUninstall = removed &&
14332                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14333                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14334                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14335                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14336                                        false, fullUninstall, userId,
14337                                        removed ? "pkg removed" : "pkg changed");
14338                            }
14339                            if (removed) {
14340                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14341                                        new String[] {ssp}, userId);
14342                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14343                                    mAppOpsService.packageRemoved(
14344                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14345
14346                                    // Remove all permissions granted from/to this package
14347                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14348                                }
14349                            }
14350                        }
14351                    }
14352                }
14353            } else {
14354                String msg = "Permission Denial: " + intent.getAction()
14355                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14356                        + ", uid=" + callingUid + ")"
14357                        + " requires "
14358                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14359                Slog.w(TAG, msg);
14360                throw new SecurityException(msg);
14361            }
14362
14363        // Special case for adding a package: by default turn on compatibility
14364        // mode.
14365        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14366            Uri data = intent.getData();
14367            String ssp;
14368            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14369                mCompatModePackages.handlePackageAddedLocked(ssp,
14370                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14371            }
14372        }
14373
14374        /*
14375         * If this is the time zone changed action, queue up a message that will reset the timezone
14376         * of all currently running processes. This message will get queued up before the broadcast
14377         * happens.
14378         */
14379        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14380            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14381        }
14382
14383        /*
14384         * If the user set the time, let all running processes know.
14385         */
14386        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14387            final int is24Hour = intent.getBooleanExtra(
14388                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14389            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14390        }
14391
14392        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14393            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14394        }
14395
14396        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14397            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14398            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14399        }
14400
14401        // Add to the sticky list if requested.
14402        if (sticky) {
14403            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14404                    callingPid, callingUid)
14405                    != PackageManager.PERMISSION_GRANTED) {
14406                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14407                        + callingPid + ", uid=" + callingUid
14408                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14409                Slog.w(TAG, msg);
14410                throw new SecurityException(msg);
14411            }
14412            if (requiredPermission != null) {
14413                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14414                        + " and enforce permission " + requiredPermission);
14415                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14416            }
14417            if (intent.getComponent() != null) {
14418                throw new SecurityException(
14419                        "Sticky broadcasts can't target a specific component");
14420            }
14421            // We use userId directly here, since the "all" target is maintained
14422            // as a separate set of sticky broadcasts.
14423            if (userId != UserHandle.USER_ALL) {
14424                // But first, if this is not a broadcast to all users, then
14425                // make sure it doesn't conflict with an existing broadcast to
14426                // all users.
14427                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14428                        UserHandle.USER_ALL);
14429                if (stickies != null) {
14430                    ArrayList<Intent> list = stickies.get(intent.getAction());
14431                    if (list != null) {
14432                        int N = list.size();
14433                        int i;
14434                        for (i=0; i<N; i++) {
14435                            if (intent.filterEquals(list.get(i))) {
14436                                throw new IllegalArgumentException(
14437                                        "Sticky broadcast " + intent + " for user "
14438                                        + userId + " conflicts with existing global broadcast");
14439                            }
14440                        }
14441                    }
14442                }
14443            }
14444            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14445            if (stickies == null) {
14446                stickies = new ArrayMap<String, ArrayList<Intent>>();
14447                mStickyBroadcasts.put(userId, stickies);
14448            }
14449            ArrayList<Intent> list = stickies.get(intent.getAction());
14450            if (list == null) {
14451                list = new ArrayList<Intent>();
14452                stickies.put(intent.getAction(), list);
14453            }
14454            int N = list.size();
14455            int i;
14456            for (i=0; i<N; i++) {
14457                if (intent.filterEquals(list.get(i))) {
14458                    // This sticky already exists, replace it.
14459                    list.set(i, new Intent(intent));
14460                    break;
14461                }
14462            }
14463            if (i >= N) {
14464                list.add(new Intent(intent));
14465            }
14466        }
14467
14468        int[] users;
14469        if (userId == UserHandle.USER_ALL) {
14470            // Caller wants broadcast to go to all started users.
14471            users = mStartedUserArray;
14472        } else {
14473            // Caller wants broadcast to go to one specific user.
14474            users = new int[] {userId};
14475        }
14476
14477        // Figure out who all will receive this broadcast.
14478        List receivers = null;
14479        List<BroadcastFilter> registeredReceivers = null;
14480        // Need to resolve the intent to interested receivers...
14481        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14482                 == 0) {
14483            receivers = collectReceiverComponents(intent, resolvedType, users);
14484        }
14485        if (intent.getComponent() == null) {
14486            registeredReceivers = mReceiverResolver.queryIntent(intent,
14487                    resolvedType, false, userId);
14488        }
14489
14490        final boolean replacePending =
14491                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14492
14493        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14494                + " replacePending=" + replacePending);
14495
14496        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14497        if (!ordered && NR > 0) {
14498            // If we are not serializing this broadcast, then send the
14499            // registered receivers separately so they don't wait for the
14500            // components to be launched.
14501            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14502            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14503                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14504                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14505                    ordered, sticky, false, userId);
14506            if (DEBUG_BROADCAST) Slog.v(
14507                    TAG, "Enqueueing parallel broadcast " + r);
14508            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14509            if (!replaced) {
14510                queue.enqueueParallelBroadcastLocked(r);
14511                queue.scheduleBroadcastsLocked();
14512            }
14513            registeredReceivers = null;
14514            NR = 0;
14515        }
14516
14517        // Merge into one list.
14518        int ir = 0;
14519        if (receivers != null) {
14520            // A special case for PACKAGE_ADDED: do not allow the package
14521            // being added to see this broadcast.  This prevents them from
14522            // using this as a back door to get run as soon as they are
14523            // installed.  Maybe in the future we want to have a special install
14524            // broadcast or such for apps, but we'd like to deliberately make
14525            // this decision.
14526            String skipPackages[] = null;
14527            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14528                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14529                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14530                Uri data = intent.getData();
14531                if (data != null) {
14532                    String pkgName = data.getSchemeSpecificPart();
14533                    if (pkgName != null) {
14534                        skipPackages = new String[] { pkgName };
14535                    }
14536                }
14537            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14538                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14539            }
14540            if (skipPackages != null && (skipPackages.length > 0)) {
14541                for (String skipPackage : skipPackages) {
14542                    if (skipPackage != null) {
14543                        int NT = receivers.size();
14544                        for (int it=0; it<NT; it++) {
14545                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14546                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14547                                receivers.remove(it);
14548                                it--;
14549                                NT--;
14550                            }
14551                        }
14552                    }
14553                }
14554            }
14555
14556            int NT = receivers != null ? receivers.size() : 0;
14557            int it = 0;
14558            ResolveInfo curt = null;
14559            BroadcastFilter curr = null;
14560            while (it < NT && ir < NR) {
14561                if (curt == null) {
14562                    curt = (ResolveInfo)receivers.get(it);
14563                }
14564                if (curr == null) {
14565                    curr = registeredReceivers.get(ir);
14566                }
14567                if (curr.getPriority() >= curt.priority) {
14568                    // Insert this broadcast record into the final list.
14569                    receivers.add(it, curr);
14570                    ir++;
14571                    curr = null;
14572                    it++;
14573                    NT++;
14574                } else {
14575                    // Skip to the next ResolveInfo in the final list.
14576                    it++;
14577                    curt = null;
14578                }
14579            }
14580        }
14581        while (ir < NR) {
14582            if (receivers == null) {
14583                receivers = new ArrayList();
14584            }
14585            receivers.add(registeredReceivers.get(ir));
14586            ir++;
14587        }
14588
14589        if ((receivers != null && receivers.size() > 0)
14590                || resultTo != null) {
14591            BroadcastQueue queue = broadcastQueueForIntent(intent);
14592            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14593                    callerPackage, callingPid, callingUid, resolvedType,
14594                    requiredPermission, appOp, receivers, resultTo, resultCode,
14595                    resultData, map, ordered, sticky, false, userId);
14596            if (DEBUG_BROADCAST) Slog.v(
14597                    TAG, "Enqueueing ordered broadcast " + r
14598                    + ": prev had " + queue.mOrderedBroadcasts.size());
14599            if (DEBUG_BROADCAST) {
14600                int seq = r.intent.getIntExtra("seq", -1);
14601                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14602            }
14603            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14604            if (!replaced) {
14605                queue.enqueueOrderedBroadcastLocked(r);
14606                queue.scheduleBroadcastsLocked();
14607            }
14608        }
14609
14610        return ActivityManager.BROADCAST_SUCCESS;
14611    }
14612
14613    final Intent verifyBroadcastLocked(Intent intent) {
14614        // Refuse possible leaked file descriptors
14615        if (intent != null && intent.hasFileDescriptors() == true) {
14616            throw new IllegalArgumentException("File descriptors passed in Intent");
14617        }
14618
14619        int flags = intent.getFlags();
14620
14621        if (!mProcessesReady) {
14622            // if the caller really truly claims to know what they're doing, go
14623            // ahead and allow the broadcast without launching any receivers
14624            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14625                intent = new Intent(intent);
14626                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14627            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14628                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14629                        + " before boot completion");
14630                throw new IllegalStateException("Cannot broadcast before boot completed");
14631            }
14632        }
14633
14634        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14635            throw new IllegalArgumentException(
14636                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14637        }
14638
14639        return intent;
14640    }
14641
14642    public final int broadcastIntent(IApplicationThread caller,
14643            Intent intent, String resolvedType, IIntentReceiver resultTo,
14644            int resultCode, String resultData, Bundle map,
14645            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14646        enforceNotIsolatedCaller("broadcastIntent");
14647        synchronized(this) {
14648            intent = verifyBroadcastLocked(intent);
14649
14650            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14651            final int callingPid = Binder.getCallingPid();
14652            final int callingUid = Binder.getCallingUid();
14653            final long origId = Binder.clearCallingIdentity();
14654            int res = broadcastIntentLocked(callerApp,
14655                    callerApp != null ? callerApp.info.packageName : null,
14656                    intent, resolvedType, resultTo,
14657                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14658                    callingPid, callingUid, userId);
14659            Binder.restoreCallingIdentity(origId);
14660            return res;
14661        }
14662    }
14663
14664    int broadcastIntentInPackage(String packageName, int uid,
14665            Intent intent, String resolvedType, IIntentReceiver resultTo,
14666            int resultCode, String resultData, Bundle map,
14667            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14668        synchronized(this) {
14669            intent = verifyBroadcastLocked(intent);
14670
14671            final long origId = Binder.clearCallingIdentity();
14672            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14673                    resultTo, resultCode, resultData, map, requiredPermission,
14674                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14675            Binder.restoreCallingIdentity(origId);
14676            return res;
14677        }
14678    }
14679
14680    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14681        // Refuse possible leaked file descriptors
14682        if (intent != null && intent.hasFileDescriptors() == true) {
14683            throw new IllegalArgumentException("File descriptors passed in Intent");
14684        }
14685
14686        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14687                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14688
14689        synchronized(this) {
14690            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14691                    != PackageManager.PERMISSION_GRANTED) {
14692                String msg = "Permission Denial: unbroadcastIntent() from pid="
14693                        + Binder.getCallingPid()
14694                        + ", uid=" + Binder.getCallingUid()
14695                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14696                Slog.w(TAG, msg);
14697                throw new SecurityException(msg);
14698            }
14699            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14700            if (stickies != null) {
14701                ArrayList<Intent> list = stickies.get(intent.getAction());
14702                if (list != null) {
14703                    int N = list.size();
14704                    int i;
14705                    for (i=0; i<N; i++) {
14706                        if (intent.filterEquals(list.get(i))) {
14707                            list.remove(i);
14708                            break;
14709                        }
14710                    }
14711                    if (list.size() <= 0) {
14712                        stickies.remove(intent.getAction());
14713                    }
14714                }
14715                if (stickies.size() <= 0) {
14716                    mStickyBroadcasts.remove(userId);
14717                }
14718            }
14719        }
14720    }
14721
14722    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14723            String resultData, Bundle resultExtras, boolean resultAbort) {
14724        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14725        if (r == null) {
14726            Slog.w(TAG, "finishReceiver called but not found on queue");
14727            return false;
14728        }
14729
14730        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14731    }
14732
14733    void backgroundServicesFinishedLocked(int userId) {
14734        for (BroadcastQueue queue : mBroadcastQueues) {
14735            queue.backgroundServicesFinishedLocked(userId);
14736        }
14737    }
14738
14739    public void finishReceiver(IBinder who, int resultCode, String resultData,
14740            Bundle resultExtras, boolean resultAbort) {
14741        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14742
14743        // Refuse possible leaked file descriptors
14744        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14745            throw new IllegalArgumentException("File descriptors passed in Bundle");
14746        }
14747
14748        final long origId = Binder.clearCallingIdentity();
14749        try {
14750            boolean doNext = false;
14751            BroadcastRecord r;
14752
14753            synchronized(this) {
14754                r = broadcastRecordForReceiverLocked(who);
14755                if (r != null) {
14756                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14757                        resultData, resultExtras, resultAbort, true);
14758                }
14759            }
14760
14761            if (doNext) {
14762                r.queue.processNextBroadcast(false);
14763            }
14764            trimApplications();
14765        } finally {
14766            Binder.restoreCallingIdentity(origId);
14767        }
14768    }
14769
14770    // =========================================================
14771    // INSTRUMENTATION
14772    // =========================================================
14773
14774    public boolean startInstrumentation(ComponentName className,
14775            String profileFile, int flags, Bundle arguments,
14776            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14777            int userId, String abiOverride) {
14778        enforceNotIsolatedCaller("startInstrumentation");
14779        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14780                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14781        // Refuse possible leaked file descriptors
14782        if (arguments != null && arguments.hasFileDescriptors()) {
14783            throw new IllegalArgumentException("File descriptors passed in Bundle");
14784        }
14785
14786        synchronized(this) {
14787            InstrumentationInfo ii = null;
14788            ApplicationInfo ai = null;
14789            try {
14790                ii = mContext.getPackageManager().getInstrumentationInfo(
14791                    className, STOCK_PM_FLAGS);
14792                ai = AppGlobals.getPackageManager().getApplicationInfo(
14793                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14794            } catch (PackageManager.NameNotFoundException e) {
14795            } catch (RemoteException e) {
14796            }
14797            if (ii == null) {
14798                reportStartInstrumentationFailure(watcher, className,
14799                        "Unable to find instrumentation info for: " + className);
14800                return false;
14801            }
14802            if (ai == null) {
14803                reportStartInstrumentationFailure(watcher, className,
14804                        "Unable to find instrumentation target package: " + ii.targetPackage);
14805                return false;
14806            }
14807
14808            int match = mContext.getPackageManager().checkSignatures(
14809                    ii.targetPackage, ii.packageName);
14810            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14811                String msg = "Permission Denial: starting instrumentation "
14812                        + className + " from pid="
14813                        + Binder.getCallingPid()
14814                        + ", uid=" + Binder.getCallingPid()
14815                        + " not allowed because package " + ii.packageName
14816                        + " does not have a signature matching the target "
14817                        + ii.targetPackage;
14818                reportStartInstrumentationFailure(watcher, className, msg);
14819                throw new SecurityException(msg);
14820            }
14821
14822            final long origId = Binder.clearCallingIdentity();
14823            // Instrumentation can kill and relaunch even persistent processes
14824            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14825                    "start instr");
14826            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14827            app.instrumentationClass = className;
14828            app.instrumentationInfo = ai;
14829            app.instrumentationProfileFile = profileFile;
14830            app.instrumentationArguments = arguments;
14831            app.instrumentationWatcher = watcher;
14832            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14833            app.instrumentationResultClass = className;
14834            Binder.restoreCallingIdentity(origId);
14835        }
14836
14837        return true;
14838    }
14839
14840    /**
14841     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14842     * error to the logs, but if somebody is watching, send the report there too.  This enables
14843     * the "am" command to report errors with more information.
14844     *
14845     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14846     * @param cn The component name of the instrumentation.
14847     * @param report The error report.
14848     */
14849    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14850            ComponentName cn, String report) {
14851        Slog.w(TAG, report);
14852        try {
14853            if (watcher != null) {
14854                Bundle results = new Bundle();
14855                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14856                results.putString("Error", report);
14857                watcher.instrumentationStatus(cn, -1, results);
14858            }
14859        } catch (RemoteException e) {
14860            Slog.w(TAG, e);
14861        }
14862    }
14863
14864    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14865        if (app.instrumentationWatcher != null) {
14866            try {
14867                // NOTE:  IInstrumentationWatcher *must* be oneway here
14868                app.instrumentationWatcher.instrumentationFinished(
14869                    app.instrumentationClass,
14870                    resultCode,
14871                    results);
14872            } catch (RemoteException e) {
14873            }
14874        }
14875        if (app.instrumentationUiAutomationConnection != null) {
14876            try {
14877                app.instrumentationUiAutomationConnection.shutdown();
14878            } catch (RemoteException re) {
14879                /* ignore */
14880            }
14881            // Only a UiAutomation can set this flag and now that
14882            // it is finished we make sure it is reset to its default.
14883            mUserIsMonkey = false;
14884        }
14885        app.instrumentationWatcher = null;
14886        app.instrumentationUiAutomationConnection = null;
14887        app.instrumentationClass = null;
14888        app.instrumentationInfo = null;
14889        app.instrumentationProfileFile = null;
14890        app.instrumentationArguments = null;
14891
14892        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14893                "finished inst");
14894    }
14895
14896    public void finishInstrumentation(IApplicationThread target,
14897            int resultCode, Bundle results) {
14898        int userId = UserHandle.getCallingUserId();
14899        // Refuse possible leaked file descriptors
14900        if (results != null && results.hasFileDescriptors()) {
14901            throw new IllegalArgumentException("File descriptors passed in Intent");
14902        }
14903
14904        synchronized(this) {
14905            ProcessRecord app = getRecordForAppLocked(target);
14906            if (app == null) {
14907                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14908                return;
14909            }
14910            final long origId = Binder.clearCallingIdentity();
14911            finishInstrumentationLocked(app, resultCode, results);
14912            Binder.restoreCallingIdentity(origId);
14913        }
14914    }
14915
14916    // =========================================================
14917    // CONFIGURATION
14918    // =========================================================
14919
14920    public ConfigurationInfo getDeviceConfigurationInfo() {
14921        ConfigurationInfo config = new ConfigurationInfo();
14922        synchronized (this) {
14923            config.reqTouchScreen = mConfiguration.touchscreen;
14924            config.reqKeyboardType = mConfiguration.keyboard;
14925            config.reqNavigation = mConfiguration.navigation;
14926            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14927                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14928                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14929            }
14930            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14931                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14932                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14933            }
14934            config.reqGlEsVersion = GL_ES_VERSION;
14935        }
14936        return config;
14937    }
14938
14939    ActivityStack getFocusedStack() {
14940        return mStackSupervisor.getFocusedStack();
14941    }
14942
14943    public Configuration getConfiguration() {
14944        Configuration ci;
14945        synchronized(this) {
14946            ci = new Configuration(mConfiguration);
14947        }
14948        return ci;
14949    }
14950
14951    public void updatePersistentConfiguration(Configuration values) {
14952        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14953                "updateConfiguration()");
14954        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14955                "updateConfiguration()");
14956        if (values == null) {
14957            throw new NullPointerException("Configuration must not be null");
14958        }
14959
14960        synchronized(this) {
14961            final long origId = Binder.clearCallingIdentity();
14962            updateConfigurationLocked(values, null, true, false);
14963            Binder.restoreCallingIdentity(origId);
14964        }
14965    }
14966
14967    public void updateConfiguration(Configuration values) {
14968        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14969                "updateConfiguration()");
14970
14971        synchronized(this) {
14972            if (values == null && mWindowManager != null) {
14973                // sentinel: fetch the current configuration from the window manager
14974                values = mWindowManager.computeNewConfiguration();
14975            }
14976
14977            if (mWindowManager != null) {
14978                mProcessList.applyDisplaySize(mWindowManager);
14979            }
14980
14981            final long origId = Binder.clearCallingIdentity();
14982            if (values != null) {
14983                Settings.System.clearConfiguration(values);
14984            }
14985            updateConfigurationLocked(values, null, false, false);
14986            Binder.restoreCallingIdentity(origId);
14987        }
14988    }
14989
14990    /**
14991     * Do either or both things: (1) change the current configuration, and (2)
14992     * make sure the given activity is running with the (now) current
14993     * configuration.  Returns true if the activity has been left running, or
14994     * false if <var>starting</var> is being destroyed to match the new
14995     * configuration.
14996     * @param persistent TODO
14997     */
14998    boolean updateConfigurationLocked(Configuration values,
14999            ActivityRecord starting, boolean persistent, boolean initLocale) {
15000        int changes = 0;
15001
15002        if (values != null) {
15003            Configuration newConfig = new Configuration(mConfiguration);
15004            changes = newConfig.updateFrom(values);
15005            if (changes != 0) {
15006                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15007                    Slog.i(TAG, "Updating configuration to: " + values);
15008                }
15009
15010                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15011
15012                if (values.locale != null && !initLocale) {
15013                    saveLocaleLocked(values.locale,
15014                                     !values.locale.equals(mConfiguration.locale),
15015                                     values.userSetLocale);
15016                }
15017
15018                mConfigurationSeq++;
15019                if (mConfigurationSeq <= 0) {
15020                    mConfigurationSeq = 1;
15021                }
15022                newConfig.seq = mConfigurationSeq;
15023                mConfiguration = newConfig;
15024                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15025                //mUsageStatsService.noteStartConfig(newConfig);
15026
15027                final Configuration configCopy = new Configuration(mConfiguration);
15028
15029                // TODO: If our config changes, should we auto dismiss any currently
15030                // showing dialogs?
15031                mShowDialogs = shouldShowDialogs(newConfig);
15032
15033                AttributeCache ac = AttributeCache.instance();
15034                if (ac != null) {
15035                    ac.updateConfiguration(configCopy);
15036                }
15037
15038                // Make sure all resources in our process are updated
15039                // right now, so that anyone who is going to retrieve
15040                // resource values after we return will be sure to get
15041                // the new ones.  This is especially important during
15042                // boot, where the first config change needs to guarantee
15043                // all resources have that config before following boot
15044                // code is executed.
15045                mSystemThread.applyConfigurationToResources(configCopy);
15046
15047                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15048                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15049                    msg.obj = new Configuration(configCopy);
15050                    mHandler.sendMessage(msg);
15051                }
15052
15053                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15054                    ProcessRecord app = mLruProcesses.get(i);
15055                    try {
15056                        if (app.thread != null) {
15057                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15058                                    + app.processName + " new config " + mConfiguration);
15059                            app.thread.scheduleConfigurationChanged(configCopy);
15060                        }
15061                    } catch (Exception e) {
15062                    }
15063                }
15064                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15065                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15066                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15067                        | Intent.FLAG_RECEIVER_FOREGROUND);
15068                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15069                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15070                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15071                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15072                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15073                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15074                    broadcastIntentLocked(null, null, intent,
15075                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15076                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15077                }
15078            }
15079        }
15080
15081        boolean kept = true;
15082        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15083        // mainStack is null during startup.
15084        if (mainStack != null) {
15085            if (changes != 0 && starting == null) {
15086                // If the configuration changed, and the caller is not already
15087                // in the process of starting an activity, then find the top
15088                // activity to check if its configuration needs to change.
15089                starting = mainStack.topRunningActivityLocked(null);
15090            }
15091
15092            if (starting != null) {
15093                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15094                // And we need to make sure at this point that all other activities
15095                // are made visible with the correct configuration.
15096                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15097            }
15098        }
15099
15100        if (values != null && mWindowManager != null) {
15101            mWindowManager.setNewConfiguration(mConfiguration);
15102        }
15103
15104        return kept;
15105    }
15106
15107    /**
15108     * Decide based on the configuration whether we should shouw the ANR,
15109     * crash, etc dialogs.  The idea is that if there is no affordnace to
15110     * press the on-screen buttons, we shouldn't show the dialog.
15111     *
15112     * A thought: SystemUI might also want to get told about this, the Power
15113     * dialog / global actions also might want different behaviors.
15114     */
15115    private static final boolean shouldShowDialogs(Configuration config) {
15116        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15117                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15118    }
15119
15120    /**
15121     * Save the locale.  You must be inside a synchronized (this) block.
15122     */
15123    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15124        if(isDiff) {
15125            SystemProperties.set("user.language", l.getLanguage());
15126            SystemProperties.set("user.region", l.getCountry());
15127        }
15128
15129        if(isPersist) {
15130            SystemProperties.set("persist.sys.language", l.getLanguage());
15131            SystemProperties.set("persist.sys.country", l.getCountry());
15132            SystemProperties.set("persist.sys.localevar", l.getVariant());
15133        }
15134    }
15135
15136    @Override
15137    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15138        ActivityRecord srec = ActivityRecord.forToken(token);
15139        return srec != null && srec.task.affinity != null &&
15140                srec.task.affinity.equals(destAffinity);
15141    }
15142
15143    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15144            Intent resultData) {
15145
15146        synchronized (this) {
15147            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15148            if (stack != null) {
15149                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15150            }
15151            return false;
15152        }
15153    }
15154
15155    public int getLaunchedFromUid(IBinder activityToken) {
15156        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15157        if (srec == null) {
15158            return -1;
15159        }
15160        return srec.launchedFromUid;
15161    }
15162
15163    public String getLaunchedFromPackage(IBinder activityToken) {
15164        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15165        if (srec == null) {
15166            return null;
15167        }
15168        return srec.launchedFromPackage;
15169    }
15170
15171    // =========================================================
15172    // LIFETIME MANAGEMENT
15173    // =========================================================
15174
15175    // Returns which broadcast queue the app is the current [or imminent] receiver
15176    // on, or 'null' if the app is not an active broadcast recipient.
15177    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15178        BroadcastRecord r = app.curReceiver;
15179        if (r != null) {
15180            return r.queue;
15181        }
15182
15183        // It's not the current receiver, but it might be starting up to become one
15184        synchronized (this) {
15185            for (BroadcastQueue queue : mBroadcastQueues) {
15186                r = queue.mPendingBroadcast;
15187                if (r != null && r.curApp == app) {
15188                    // found it; report which queue it's in
15189                    return queue;
15190                }
15191            }
15192        }
15193
15194        return null;
15195    }
15196
15197    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15198            boolean doingAll, long now) {
15199        if (mAdjSeq == app.adjSeq) {
15200            // This adjustment has already been computed.
15201            return app.curRawAdj;
15202        }
15203
15204        if (app.thread == null) {
15205            app.adjSeq = mAdjSeq;
15206            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15207            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15208            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15209        }
15210
15211        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15212        app.adjSource = null;
15213        app.adjTarget = null;
15214        app.empty = false;
15215        app.cached = false;
15216
15217        final int activitiesSize = app.activities.size();
15218
15219        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15220            // The max adjustment doesn't allow this app to be anything
15221            // below foreground, so it is not worth doing work for it.
15222            app.adjType = "fixed";
15223            app.adjSeq = mAdjSeq;
15224            app.curRawAdj = app.maxAdj;
15225            app.foregroundActivities = false;
15226            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15227            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15228            // System processes can do UI, and when they do we want to have
15229            // them trim their memory after the user leaves the UI.  To
15230            // facilitate this, here we need to determine whether or not it
15231            // is currently showing UI.
15232            app.systemNoUi = true;
15233            if (app == TOP_APP) {
15234                app.systemNoUi = false;
15235            } else if (activitiesSize > 0) {
15236                for (int j = 0; j < activitiesSize; j++) {
15237                    final ActivityRecord r = app.activities.get(j);
15238                    if (r.visible) {
15239                        app.systemNoUi = false;
15240                    }
15241                }
15242            }
15243            if (!app.systemNoUi) {
15244                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15245            }
15246            return (app.curAdj=app.maxAdj);
15247        }
15248
15249        app.systemNoUi = false;
15250
15251        // Determine the importance of the process, starting with most
15252        // important to least, and assign an appropriate OOM adjustment.
15253        int adj;
15254        int schedGroup;
15255        int procState;
15256        boolean foregroundActivities = false;
15257        BroadcastQueue queue;
15258        if (app == TOP_APP) {
15259            // The last app on the list is the foreground app.
15260            adj = ProcessList.FOREGROUND_APP_ADJ;
15261            schedGroup = Process.THREAD_GROUP_DEFAULT;
15262            app.adjType = "top-activity";
15263            foregroundActivities = true;
15264            procState = ActivityManager.PROCESS_STATE_TOP;
15265        } else if (app.instrumentationClass != null) {
15266            // Don't want to kill running instrumentation.
15267            adj = ProcessList.FOREGROUND_APP_ADJ;
15268            schedGroup = Process.THREAD_GROUP_DEFAULT;
15269            app.adjType = "instrumentation";
15270            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15271        } else if ((queue = isReceivingBroadcast(app)) != null) {
15272            // An app that is currently receiving a broadcast also
15273            // counts as being in the foreground for OOM killer purposes.
15274            // It's placed in a sched group based on the nature of the
15275            // broadcast as reflected by which queue it's active in.
15276            adj = ProcessList.FOREGROUND_APP_ADJ;
15277            schedGroup = (queue == mFgBroadcastQueue)
15278                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15279            app.adjType = "broadcast";
15280            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15281        } else if (app.executingServices.size() > 0) {
15282            // An app that is currently executing a service callback also
15283            // counts as being in the foreground.
15284            adj = ProcessList.FOREGROUND_APP_ADJ;
15285            schedGroup = app.execServicesFg ?
15286                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15287            app.adjType = "exec-service";
15288            procState = ActivityManager.PROCESS_STATE_SERVICE;
15289            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15290        } else {
15291            // As far as we know the process is empty.  We may change our mind later.
15292            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15293            // At this point we don't actually know the adjustment.  Use the cached adj
15294            // value that the caller wants us to.
15295            adj = cachedAdj;
15296            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15297            app.cached = true;
15298            app.empty = true;
15299            app.adjType = "cch-empty";
15300        }
15301
15302        // Examine all activities if not already foreground.
15303        if (!foregroundActivities && activitiesSize > 0) {
15304            for (int j = 0; j < activitiesSize; j++) {
15305                final ActivityRecord r = app.activities.get(j);
15306                if (r.app != app) {
15307                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15308                            + app + "?!?");
15309                    continue;
15310                }
15311                if (r.visible) {
15312                    // App has a visible activity; only upgrade adjustment.
15313                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15314                        adj = ProcessList.VISIBLE_APP_ADJ;
15315                        app.adjType = "visible";
15316                    }
15317                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15318                        procState = ActivityManager.PROCESS_STATE_TOP;
15319                    }
15320                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15321                    app.cached = false;
15322                    app.empty = false;
15323                    foregroundActivities = true;
15324                    break;
15325                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15326                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15327                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15328                        app.adjType = "pausing";
15329                    }
15330                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15331                        procState = ActivityManager.PROCESS_STATE_TOP;
15332                    }
15333                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15334                    app.cached = false;
15335                    app.empty = false;
15336                    foregroundActivities = true;
15337                } else if (r.state == ActivityState.STOPPING) {
15338                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15339                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15340                        app.adjType = "stopping";
15341                    }
15342                    // For the process state, we will at this point consider the
15343                    // process to be cached.  It will be cached either as an activity
15344                    // or empty depending on whether the activity is finishing.  We do
15345                    // this so that we can treat the process as cached for purposes of
15346                    // memory trimming (determing current memory level, trim command to
15347                    // send to process) since there can be an arbitrary number of stopping
15348                    // processes and they should soon all go into the cached state.
15349                    if (!r.finishing) {
15350                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15351                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15352                        }
15353                    }
15354                    app.cached = false;
15355                    app.empty = false;
15356                    foregroundActivities = true;
15357                } else {
15358                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15359                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15360                        app.adjType = "cch-act";
15361                    }
15362                }
15363            }
15364        }
15365
15366        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15367            if (app.foregroundServices) {
15368                // The user is aware of this app, so make it visible.
15369                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15370                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15371                app.cached = false;
15372                app.adjType = "fg-service";
15373                schedGroup = Process.THREAD_GROUP_DEFAULT;
15374            } else if (app.forcingToForeground != null) {
15375                // The user is aware of this app, so make it visible.
15376                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15377                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15378                app.cached = false;
15379                app.adjType = "force-fg";
15380                app.adjSource = app.forcingToForeground;
15381                schedGroup = Process.THREAD_GROUP_DEFAULT;
15382            }
15383        }
15384
15385        if (app == mHeavyWeightProcess) {
15386            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15387                // We don't want to kill the current heavy-weight process.
15388                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15389                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15390                app.cached = false;
15391                app.adjType = "heavy";
15392            }
15393            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15394                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15395            }
15396        }
15397
15398        if (app == mHomeProcess) {
15399            if (adj > ProcessList.HOME_APP_ADJ) {
15400                // This process is hosting what we currently consider to be the
15401                // home app, so we don't want to let it go into the background.
15402                adj = ProcessList.HOME_APP_ADJ;
15403                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15404                app.cached = false;
15405                app.adjType = "home";
15406            }
15407            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15408                procState = ActivityManager.PROCESS_STATE_HOME;
15409            }
15410        }
15411
15412        if (app == mPreviousProcess && app.activities.size() > 0) {
15413            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15414                // This was the previous process that showed UI to the user.
15415                // We want to try to keep it around more aggressively, to give
15416                // a good experience around switching between two apps.
15417                adj = ProcessList.PREVIOUS_APP_ADJ;
15418                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15419                app.cached = false;
15420                app.adjType = "previous";
15421            }
15422            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15423                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15424            }
15425        }
15426
15427        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15428                + " reason=" + app.adjType);
15429
15430        // By default, we use the computed adjustment.  It may be changed if
15431        // there are applications dependent on our services or providers, but
15432        // this gives us a baseline and makes sure we don't get into an
15433        // infinite recursion.
15434        app.adjSeq = mAdjSeq;
15435        app.curRawAdj = adj;
15436        app.hasStartedServices = false;
15437
15438        if (mBackupTarget != null && app == mBackupTarget.app) {
15439            // If possible we want to avoid killing apps while they're being backed up
15440            if (adj > ProcessList.BACKUP_APP_ADJ) {
15441                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15442                adj = ProcessList.BACKUP_APP_ADJ;
15443                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15444                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15445                }
15446                app.adjType = "backup";
15447                app.cached = false;
15448            }
15449            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15450                procState = ActivityManager.PROCESS_STATE_BACKUP;
15451            }
15452        }
15453
15454        boolean mayBeTop = false;
15455
15456        for (int is = app.services.size()-1;
15457                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15458                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15459                        || procState > ActivityManager.PROCESS_STATE_TOP);
15460                is--) {
15461            ServiceRecord s = app.services.valueAt(is);
15462            if (s.startRequested) {
15463                app.hasStartedServices = true;
15464                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15465                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15466                }
15467                if (app.hasShownUi && app != mHomeProcess) {
15468                    // If this process has shown some UI, let it immediately
15469                    // go to the LRU list because it may be pretty heavy with
15470                    // UI stuff.  We'll tag it with a label just to help
15471                    // debug and understand what is going on.
15472                    if (adj > ProcessList.SERVICE_ADJ) {
15473                        app.adjType = "cch-started-ui-services";
15474                    }
15475                } else {
15476                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15477                        // This service has seen some activity within
15478                        // recent memory, so we will keep its process ahead
15479                        // of the background processes.
15480                        if (adj > ProcessList.SERVICE_ADJ) {
15481                            adj = ProcessList.SERVICE_ADJ;
15482                            app.adjType = "started-services";
15483                            app.cached = false;
15484                        }
15485                    }
15486                    // If we have let the service slide into the background
15487                    // state, still have some text describing what it is doing
15488                    // even though the service no longer has an impact.
15489                    if (adj > ProcessList.SERVICE_ADJ) {
15490                        app.adjType = "cch-started-services";
15491                    }
15492                }
15493            }
15494            for (int conni = s.connections.size()-1;
15495                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15496                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15497                            || procState > ActivityManager.PROCESS_STATE_TOP);
15498                    conni--) {
15499                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15500                for (int i = 0;
15501                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15502                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15503                                || procState > ActivityManager.PROCESS_STATE_TOP);
15504                        i++) {
15505                    // XXX should compute this based on the max of
15506                    // all connected clients.
15507                    ConnectionRecord cr = clist.get(i);
15508                    if (cr.binding.client == app) {
15509                        // Binding to ourself is not interesting.
15510                        continue;
15511                    }
15512                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15513                        ProcessRecord client = cr.binding.client;
15514                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15515                                TOP_APP, doingAll, now);
15516                        int clientProcState = client.curProcState;
15517                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15518                            // If the other app is cached for any reason, for purposes here
15519                            // we are going to consider it empty.  The specific cached state
15520                            // doesn't propagate except under certain conditions.
15521                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15522                        }
15523                        String adjType = null;
15524                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15525                            // Not doing bind OOM management, so treat
15526                            // this guy more like a started service.
15527                            if (app.hasShownUi && app != mHomeProcess) {
15528                                // If this process has shown some UI, let it immediately
15529                                // go to the LRU list because it may be pretty heavy with
15530                                // UI stuff.  We'll tag it with a label just to help
15531                                // debug and understand what is going on.
15532                                if (adj > clientAdj) {
15533                                    adjType = "cch-bound-ui-services";
15534                                }
15535                                app.cached = false;
15536                                clientAdj = adj;
15537                                clientProcState = procState;
15538                            } else {
15539                                if (now >= (s.lastActivity
15540                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15541                                    // This service has not seen activity within
15542                                    // recent memory, so allow it to drop to the
15543                                    // LRU list if there is no other reason to keep
15544                                    // it around.  We'll also tag it with a label just
15545                                    // to help debug and undertand what is going on.
15546                                    if (adj > clientAdj) {
15547                                        adjType = "cch-bound-services";
15548                                    }
15549                                    clientAdj = adj;
15550                                }
15551                            }
15552                        }
15553                        if (adj > clientAdj) {
15554                            // If this process has recently shown UI, and
15555                            // the process that is binding to it is less
15556                            // important than being visible, then we don't
15557                            // care about the binding as much as we care
15558                            // about letting this process get into the LRU
15559                            // list to be killed and restarted if needed for
15560                            // memory.
15561                            if (app.hasShownUi && app != mHomeProcess
15562                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15563                                adjType = "cch-bound-ui-services";
15564                            } else {
15565                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15566                                        |Context.BIND_IMPORTANT)) != 0) {
15567                                    adj = clientAdj;
15568                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15569                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15570                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15571                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15572                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15573                                    adj = clientAdj;
15574                                } else {
15575                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15576                                        adj = ProcessList.VISIBLE_APP_ADJ;
15577                                    }
15578                                }
15579                                if (!client.cached) {
15580                                    app.cached = false;
15581                                }
15582                                adjType = "service";
15583                            }
15584                        }
15585                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15586                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15587                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15588                            }
15589                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15590                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15591                                    // Special handling of clients who are in the top state.
15592                                    // We *may* want to consider this process to be in the
15593                                    // top state as well, but only if there is not another
15594                                    // reason for it to be running.  Being on the top is a
15595                                    // special state, meaning you are specifically running
15596                                    // for the current top app.  If the process is already
15597                                    // running in the background for some other reason, it
15598                                    // is more important to continue considering it to be
15599                                    // in the background state.
15600                                    mayBeTop = true;
15601                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15602                                } else {
15603                                    // Special handling for above-top states (persistent
15604                                    // processes).  These should not bring the current process
15605                                    // into the top state, since they are not on top.  Instead
15606                                    // give them the best state after that.
15607                                    clientProcState =
15608                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15609                                }
15610                            }
15611                        } else {
15612                            if (clientProcState <
15613                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15614                                clientProcState =
15615                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15616                            }
15617                        }
15618                        if (procState > clientProcState) {
15619                            procState = clientProcState;
15620                        }
15621                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15622                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15623                            app.pendingUiClean = true;
15624                        }
15625                        if (adjType != null) {
15626                            app.adjType = adjType;
15627                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15628                                    .REASON_SERVICE_IN_USE;
15629                            app.adjSource = cr.binding.client;
15630                            app.adjSourceProcState = clientProcState;
15631                            app.adjTarget = s.name;
15632                        }
15633                    }
15634                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15635                        app.treatLikeActivity = true;
15636                    }
15637                    final ActivityRecord a = cr.activity;
15638                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15639                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15640                                (a.visible || a.state == ActivityState.RESUMED
15641                                 || a.state == ActivityState.PAUSING)) {
15642                            adj = ProcessList.FOREGROUND_APP_ADJ;
15643                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15644                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15645                            }
15646                            app.cached = false;
15647                            app.adjType = "service";
15648                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15649                                    .REASON_SERVICE_IN_USE;
15650                            app.adjSource = a;
15651                            app.adjSourceProcState = procState;
15652                            app.adjTarget = s.name;
15653                        }
15654                    }
15655                }
15656            }
15657        }
15658
15659        for (int provi = app.pubProviders.size()-1;
15660                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15661                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15662                        || procState > ActivityManager.PROCESS_STATE_TOP);
15663                provi--) {
15664            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15665            for (int i = cpr.connections.size()-1;
15666                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15667                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15668                            || procState > ActivityManager.PROCESS_STATE_TOP);
15669                    i--) {
15670                ContentProviderConnection conn = cpr.connections.get(i);
15671                ProcessRecord client = conn.client;
15672                if (client == app) {
15673                    // Being our own client is not interesting.
15674                    continue;
15675                }
15676                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15677                int clientProcState = client.curProcState;
15678                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15679                    // If the other app is cached for any reason, for purposes here
15680                    // we are going to consider it empty.
15681                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15682                }
15683                if (adj > clientAdj) {
15684                    if (app.hasShownUi && app != mHomeProcess
15685                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15686                        app.adjType = "cch-ui-provider";
15687                    } else {
15688                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15689                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15690                        app.adjType = "provider";
15691                    }
15692                    app.cached &= client.cached;
15693                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15694                            .REASON_PROVIDER_IN_USE;
15695                    app.adjSource = client;
15696                    app.adjSourceProcState = clientProcState;
15697                    app.adjTarget = cpr.name;
15698                }
15699                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15700                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15701                        // Special handling of clients who are in the top state.
15702                        // We *may* want to consider this process to be in the
15703                        // top state as well, but only if there is not another
15704                        // reason for it to be running.  Being on the top is a
15705                        // special state, meaning you are specifically running
15706                        // for the current top app.  If the process is already
15707                        // running in the background for some other reason, it
15708                        // is more important to continue considering it to be
15709                        // in the background state.
15710                        mayBeTop = true;
15711                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15712                    } else {
15713                        // Special handling for above-top states (persistent
15714                        // processes).  These should not bring the current process
15715                        // into the top state, since they are not on top.  Instead
15716                        // give them the best state after that.
15717                        clientProcState =
15718                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15719                    }
15720                }
15721                if (procState > clientProcState) {
15722                    procState = clientProcState;
15723                }
15724                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15725                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15726                }
15727            }
15728            // If the provider has external (non-framework) process
15729            // dependencies, ensure that its adjustment is at least
15730            // FOREGROUND_APP_ADJ.
15731            if (cpr.hasExternalProcessHandles()) {
15732                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15733                    adj = ProcessList.FOREGROUND_APP_ADJ;
15734                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15735                    app.cached = false;
15736                    app.adjType = "provider";
15737                    app.adjTarget = cpr.name;
15738                }
15739                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15740                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15741                }
15742            }
15743        }
15744
15745        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15746            // A client of one of our services or providers is in the top state.  We
15747            // *may* want to be in the top state, but not if we are already running in
15748            // the background for some other reason.  For the decision here, we are going
15749            // to pick out a few specific states that we want to remain in when a client
15750            // is top (states that tend to be longer-term) and otherwise allow it to go
15751            // to the top state.
15752            switch (procState) {
15753                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15754                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15755                case ActivityManager.PROCESS_STATE_SERVICE:
15756                    // These all are longer-term states, so pull them up to the top
15757                    // of the background states, but not all the way to the top state.
15758                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15759                    break;
15760                default:
15761                    // Otherwise, top is a better choice, so take it.
15762                    procState = ActivityManager.PROCESS_STATE_TOP;
15763                    break;
15764            }
15765        }
15766
15767        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15768            if (app.hasClientActivities) {
15769                // This is a cached process, but with client activities.  Mark it so.
15770                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15771                app.adjType = "cch-client-act";
15772            } else if (app.treatLikeActivity) {
15773                // This is a cached process, but somebody wants us to treat it like it has
15774                // an activity, okay!
15775                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15776                app.adjType = "cch-as-act";
15777            }
15778        }
15779
15780        if (adj == ProcessList.SERVICE_ADJ) {
15781            if (doingAll) {
15782                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15783                mNewNumServiceProcs++;
15784                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15785                if (!app.serviceb) {
15786                    // This service isn't far enough down on the LRU list to
15787                    // normally be a B service, but if we are low on RAM and it
15788                    // is large we want to force it down since we would prefer to
15789                    // keep launcher over it.
15790                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15791                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15792                        app.serviceHighRam = true;
15793                        app.serviceb = true;
15794                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15795                    } else {
15796                        mNewNumAServiceProcs++;
15797                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15798                    }
15799                } else {
15800                    app.serviceHighRam = false;
15801                }
15802            }
15803            if (app.serviceb) {
15804                adj = ProcessList.SERVICE_B_ADJ;
15805            }
15806        }
15807
15808        app.curRawAdj = adj;
15809
15810        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15811        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15812        if (adj > app.maxAdj) {
15813            adj = app.maxAdj;
15814            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15815                schedGroup = Process.THREAD_GROUP_DEFAULT;
15816            }
15817        }
15818
15819        // Do final modification to adj.  Everything we do between here and applying
15820        // the final setAdj must be done in this function, because we will also use
15821        // it when computing the final cached adj later.  Note that we don't need to
15822        // worry about this for max adj above, since max adj will always be used to
15823        // keep it out of the cached vaues.
15824        app.curAdj = app.modifyRawOomAdj(adj);
15825        app.curSchedGroup = schedGroup;
15826        app.curProcState = procState;
15827        app.foregroundActivities = foregroundActivities;
15828
15829        return app.curRawAdj;
15830    }
15831
15832    /**
15833     * Schedule PSS collection of a process.
15834     */
15835    void requestPssLocked(ProcessRecord proc, int procState) {
15836        if (mPendingPssProcesses.contains(proc)) {
15837            return;
15838        }
15839        if (mPendingPssProcesses.size() == 0) {
15840            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15841        }
15842        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15843        proc.pssProcState = procState;
15844        mPendingPssProcesses.add(proc);
15845    }
15846
15847    /**
15848     * Schedule PSS collection of all processes.
15849     */
15850    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15851        if (!always) {
15852            if (now < (mLastFullPssTime +
15853                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15854                return;
15855            }
15856        }
15857        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15858        mLastFullPssTime = now;
15859        mFullPssPending = true;
15860        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15861        mPendingPssProcesses.clear();
15862        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15863            ProcessRecord app = mLruProcesses.get(i);
15864            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15865                app.pssProcState = app.setProcState;
15866                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15867                        isSleeping(), now);
15868                mPendingPssProcesses.add(app);
15869            }
15870        }
15871        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15872    }
15873
15874    /**
15875     * Ask a given process to GC right now.
15876     */
15877    final void performAppGcLocked(ProcessRecord app) {
15878        try {
15879            app.lastRequestedGc = SystemClock.uptimeMillis();
15880            if (app.thread != null) {
15881                if (app.reportLowMemory) {
15882                    app.reportLowMemory = false;
15883                    app.thread.scheduleLowMemory();
15884                } else {
15885                    app.thread.processInBackground();
15886                }
15887            }
15888        } catch (Exception e) {
15889            // whatever.
15890        }
15891    }
15892
15893    /**
15894     * Returns true if things are idle enough to perform GCs.
15895     */
15896    private final boolean canGcNowLocked() {
15897        boolean processingBroadcasts = false;
15898        for (BroadcastQueue q : mBroadcastQueues) {
15899            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15900                processingBroadcasts = true;
15901            }
15902        }
15903        return !processingBroadcasts
15904                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15905    }
15906
15907    /**
15908     * Perform GCs on all processes that are waiting for it, but only
15909     * if things are idle.
15910     */
15911    final void performAppGcsLocked() {
15912        final int N = mProcessesToGc.size();
15913        if (N <= 0) {
15914            return;
15915        }
15916        if (canGcNowLocked()) {
15917            while (mProcessesToGc.size() > 0) {
15918                ProcessRecord proc = mProcessesToGc.remove(0);
15919                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15920                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15921                            <= SystemClock.uptimeMillis()) {
15922                        // To avoid spamming the system, we will GC processes one
15923                        // at a time, waiting a few seconds between each.
15924                        performAppGcLocked(proc);
15925                        scheduleAppGcsLocked();
15926                        return;
15927                    } else {
15928                        // It hasn't been long enough since we last GCed this
15929                        // process...  put it in the list to wait for its time.
15930                        addProcessToGcListLocked(proc);
15931                        break;
15932                    }
15933                }
15934            }
15935
15936            scheduleAppGcsLocked();
15937        }
15938    }
15939
15940    /**
15941     * If all looks good, perform GCs on all processes waiting for them.
15942     */
15943    final void performAppGcsIfAppropriateLocked() {
15944        if (canGcNowLocked()) {
15945            performAppGcsLocked();
15946            return;
15947        }
15948        // Still not idle, wait some more.
15949        scheduleAppGcsLocked();
15950    }
15951
15952    /**
15953     * Schedule the execution of all pending app GCs.
15954     */
15955    final void scheduleAppGcsLocked() {
15956        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15957
15958        if (mProcessesToGc.size() > 0) {
15959            // Schedule a GC for the time to the next process.
15960            ProcessRecord proc = mProcessesToGc.get(0);
15961            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15962
15963            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15964            long now = SystemClock.uptimeMillis();
15965            if (when < (now+GC_TIMEOUT)) {
15966                when = now + GC_TIMEOUT;
15967            }
15968            mHandler.sendMessageAtTime(msg, when);
15969        }
15970    }
15971
15972    /**
15973     * Add a process to the array of processes waiting to be GCed.  Keeps the
15974     * list in sorted order by the last GC time.  The process can't already be
15975     * on the list.
15976     */
15977    final void addProcessToGcListLocked(ProcessRecord proc) {
15978        boolean added = false;
15979        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15980            if (mProcessesToGc.get(i).lastRequestedGc <
15981                    proc.lastRequestedGc) {
15982                added = true;
15983                mProcessesToGc.add(i+1, proc);
15984                break;
15985            }
15986        }
15987        if (!added) {
15988            mProcessesToGc.add(0, proc);
15989        }
15990    }
15991
15992    /**
15993     * Set up to ask a process to GC itself.  This will either do it
15994     * immediately, or put it on the list of processes to gc the next
15995     * time things are idle.
15996     */
15997    final void scheduleAppGcLocked(ProcessRecord app) {
15998        long now = SystemClock.uptimeMillis();
15999        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16000            return;
16001        }
16002        if (!mProcessesToGc.contains(app)) {
16003            addProcessToGcListLocked(app);
16004            scheduleAppGcsLocked();
16005        }
16006    }
16007
16008    final void checkExcessivePowerUsageLocked(boolean doKills) {
16009        updateCpuStatsNow();
16010
16011        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16012        boolean doWakeKills = doKills;
16013        boolean doCpuKills = doKills;
16014        if (mLastPowerCheckRealtime == 0) {
16015            doWakeKills = false;
16016        }
16017        if (mLastPowerCheckUptime == 0) {
16018            doCpuKills = false;
16019        }
16020        if (stats.isScreenOn()) {
16021            doWakeKills = false;
16022        }
16023        final long curRealtime = SystemClock.elapsedRealtime();
16024        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16025        final long curUptime = SystemClock.uptimeMillis();
16026        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16027        mLastPowerCheckRealtime = curRealtime;
16028        mLastPowerCheckUptime = curUptime;
16029        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16030            doWakeKills = false;
16031        }
16032        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16033            doCpuKills = false;
16034        }
16035        int i = mLruProcesses.size();
16036        while (i > 0) {
16037            i--;
16038            ProcessRecord app = mLruProcesses.get(i);
16039            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16040                long wtime;
16041                synchronized (stats) {
16042                    wtime = stats.getProcessWakeTime(app.info.uid,
16043                            app.pid, curRealtime);
16044                }
16045                long wtimeUsed = wtime - app.lastWakeTime;
16046                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16047                if (DEBUG_POWER) {
16048                    StringBuilder sb = new StringBuilder(128);
16049                    sb.append("Wake for ");
16050                    app.toShortString(sb);
16051                    sb.append(": over ");
16052                    TimeUtils.formatDuration(realtimeSince, sb);
16053                    sb.append(" used ");
16054                    TimeUtils.formatDuration(wtimeUsed, sb);
16055                    sb.append(" (");
16056                    sb.append((wtimeUsed*100)/realtimeSince);
16057                    sb.append("%)");
16058                    Slog.i(TAG, sb.toString());
16059                    sb.setLength(0);
16060                    sb.append("CPU for ");
16061                    app.toShortString(sb);
16062                    sb.append(": over ");
16063                    TimeUtils.formatDuration(uptimeSince, sb);
16064                    sb.append(" used ");
16065                    TimeUtils.formatDuration(cputimeUsed, sb);
16066                    sb.append(" (");
16067                    sb.append((cputimeUsed*100)/uptimeSince);
16068                    sb.append("%)");
16069                    Slog.i(TAG, sb.toString());
16070                }
16071                // If a process has held a wake lock for more
16072                // than 50% of the time during this period,
16073                // that sounds bad.  Kill!
16074                if (doWakeKills && realtimeSince > 0
16075                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16076                    synchronized (stats) {
16077                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16078                                realtimeSince, wtimeUsed);
16079                    }
16080                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16081                            + " during " + realtimeSince);
16082                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16083                } else if (doCpuKills && uptimeSince > 0
16084                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16085                    synchronized (stats) {
16086                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16087                                uptimeSince, cputimeUsed);
16088                    }
16089                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16090                            + " during " + uptimeSince);
16091                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16092                } else {
16093                    app.lastWakeTime = wtime;
16094                    app.lastCpuTime = app.curCpuTime;
16095                }
16096            }
16097        }
16098    }
16099
16100    private final boolean applyOomAdjLocked(ProcessRecord app,
16101            ProcessRecord TOP_APP, boolean doingAll, long now) {
16102        boolean success = true;
16103
16104        if (app.curRawAdj != app.setRawAdj) {
16105            app.setRawAdj = app.curRawAdj;
16106        }
16107
16108        int changes = 0;
16109
16110        if (app.curAdj != app.setAdj) {
16111            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16112            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16113                TAG, "Set " + app.pid + " " + app.processName +
16114                " adj " + app.curAdj + ": " + app.adjType);
16115            app.setAdj = app.curAdj;
16116        }
16117
16118        if (app.setSchedGroup != app.curSchedGroup) {
16119            app.setSchedGroup = app.curSchedGroup;
16120            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16121                    "Setting process group of " + app.processName
16122                    + " to " + app.curSchedGroup);
16123            if (app.waitingToKill != null &&
16124                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16125                killUnneededProcessLocked(app, app.waitingToKill);
16126                success = false;
16127            } else {
16128                if (true) {
16129                    long oldId = Binder.clearCallingIdentity();
16130                    try {
16131                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16132                    } catch (Exception e) {
16133                        Slog.w(TAG, "Failed setting process group of " + app.pid
16134                                + " to " + app.curSchedGroup);
16135                        e.printStackTrace();
16136                    } finally {
16137                        Binder.restoreCallingIdentity(oldId);
16138                    }
16139                } else {
16140                    if (app.thread != null) {
16141                        try {
16142                            app.thread.setSchedulingGroup(app.curSchedGroup);
16143                        } catch (RemoteException e) {
16144                        }
16145                    }
16146                }
16147                Process.setSwappiness(app.pid,
16148                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16149            }
16150        }
16151        if (app.repForegroundActivities != app.foregroundActivities) {
16152            app.repForegroundActivities = app.foregroundActivities;
16153            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16154        }
16155        if (app.repProcState != app.curProcState) {
16156            app.repProcState = app.curProcState;
16157            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16158            if (app.thread != null) {
16159                try {
16160                    if (false) {
16161                        //RuntimeException h = new RuntimeException("here");
16162                        Slog.i(TAG, "Sending new process state " + app.repProcState
16163                                + " to " + app /*, h*/);
16164                    }
16165                    app.thread.setProcessState(app.repProcState);
16166                } catch (RemoteException e) {
16167                }
16168            }
16169        }
16170        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16171                app.setProcState)) {
16172            app.lastStateTime = now;
16173            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16174                    isSleeping(), now);
16175            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16176                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16177                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16178                    + (app.nextPssTime-now) + ": " + app);
16179        } else {
16180            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16181                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16182                requestPssLocked(app, app.setProcState);
16183                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16184                        isSleeping(), now);
16185            } else if (false && DEBUG_PSS) {
16186                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16187            }
16188        }
16189        if (app.setProcState != app.curProcState) {
16190            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16191                    "Proc state change of " + app.processName
16192                    + " to " + app.curProcState);
16193            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16194            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16195            if (setImportant && !curImportant) {
16196                // This app is no longer something we consider important enough to allow to
16197                // use arbitrary amounts of battery power.  Note
16198                // its current wake lock time to later know to kill it if
16199                // it is not behaving well.
16200                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16201                synchronized (stats) {
16202                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16203                            app.pid, SystemClock.elapsedRealtime());
16204                }
16205                app.lastCpuTime = app.curCpuTime;
16206
16207            }
16208            app.setProcState = app.curProcState;
16209            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16210                app.notCachedSinceIdle = false;
16211            }
16212            if (!doingAll) {
16213                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16214            } else {
16215                app.procStateChanged = true;
16216            }
16217        }
16218
16219        if (changes != 0) {
16220            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16221            int i = mPendingProcessChanges.size()-1;
16222            ProcessChangeItem item = null;
16223            while (i >= 0) {
16224                item = mPendingProcessChanges.get(i);
16225                if (item.pid == app.pid) {
16226                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16227                    break;
16228                }
16229                i--;
16230            }
16231            if (i < 0) {
16232                // No existing item in pending changes; need a new one.
16233                final int NA = mAvailProcessChanges.size();
16234                if (NA > 0) {
16235                    item = mAvailProcessChanges.remove(NA-1);
16236                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16237                } else {
16238                    item = new ProcessChangeItem();
16239                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16240                }
16241                item.changes = 0;
16242                item.pid = app.pid;
16243                item.uid = app.info.uid;
16244                if (mPendingProcessChanges.size() == 0) {
16245                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16246                            "*** Enqueueing dispatch processes changed!");
16247                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16248                }
16249                mPendingProcessChanges.add(item);
16250            }
16251            item.changes |= changes;
16252            item.processState = app.repProcState;
16253            item.foregroundActivities = app.repForegroundActivities;
16254            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16255                    + Integer.toHexString(System.identityHashCode(item))
16256                    + " " + app.toShortString() + ": changes=" + item.changes
16257                    + " procState=" + item.processState
16258                    + " foreground=" + item.foregroundActivities
16259                    + " type=" + app.adjType + " source=" + app.adjSource
16260                    + " target=" + app.adjTarget);
16261        }
16262
16263        return success;
16264    }
16265
16266    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16267        if (proc.thread != null) {
16268            if (proc.baseProcessTracker != null) {
16269                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16270            }
16271            if (proc.repProcState >= 0) {
16272                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16273                        proc.repProcState);
16274            }
16275        }
16276    }
16277
16278    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16279            ProcessRecord TOP_APP, boolean doingAll, long now) {
16280        if (app.thread == null) {
16281            return false;
16282        }
16283
16284        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16285
16286        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16287    }
16288
16289    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16290            boolean oomAdj) {
16291        if (isForeground != proc.foregroundServices) {
16292            proc.foregroundServices = isForeground;
16293            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16294                    proc.info.uid);
16295            if (isForeground) {
16296                if (curProcs == null) {
16297                    curProcs = new ArrayList<ProcessRecord>();
16298                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16299                }
16300                if (!curProcs.contains(proc)) {
16301                    curProcs.add(proc);
16302                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16303                            proc.info.packageName, proc.info.uid);
16304                }
16305            } else {
16306                if (curProcs != null) {
16307                    if (curProcs.remove(proc)) {
16308                        mBatteryStatsService.noteEvent(
16309                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16310                                proc.info.packageName, proc.info.uid);
16311                        if (curProcs.size() <= 0) {
16312                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16313                        }
16314                    }
16315                }
16316            }
16317            if (oomAdj) {
16318                updateOomAdjLocked();
16319            }
16320        }
16321    }
16322
16323    private final ActivityRecord resumedAppLocked() {
16324        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16325        String pkg;
16326        int uid;
16327        if (act != null) {
16328            pkg = act.packageName;
16329            uid = act.info.applicationInfo.uid;
16330        } else {
16331            pkg = null;
16332            uid = -1;
16333        }
16334        // Has the UID or resumed package name changed?
16335        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16336                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16337            if (mCurResumedPackage != null) {
16338                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16339                        mCurResumedPackage, mCurResumedUid);
16340            }
16341            mCurResumedPackage = pkg;
16342            mCurResumedUid = uid;
16343            if (mCurResumedPackage != null) {
16344                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16345                        mCurResumedPackage, mCurResumedUid);
16346            }
16347        }
16348        return act;
16349    }
16350
16351    final boolean updateOomAdjLocked(ProcessRecord app) {
16352        final ActivityRecord TOP_ACT = resumedAppLocked();
16353        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16354        final boolean wasCached = app.cached;
16355
16356        mAdjSeq++;
16357
16358        // This is the desired cached adjusment we want to tell it to use.
16359        // If our app is currently cached, we know it, and that is it.  Otherwise,
16360        // we don't know it yet, and it needs to now be cached we will then
16361        // need to do a complete oom adj.
16362        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16363                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16364        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16365                SystemClock.uptimeMillis());
16366        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16367            // Changed to/from cached state, so apps after it in the LRU
16368            // list may also be changed.
16369            updateOomAdjLocked();
16370        }
16371        return success;
16372    }
16373
16374    final void updateOomAdjLocked() {
16375        final ActivityRecord TOP_ACT = resumedAppLocked();
16376        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16377        final long now = SystemClock.uptimeMillis();
16378        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16379        final int N = mLruProcesses.size();
16380
16381        if (false) {
16382            RuntimeException e = new RuntimeException();
16383            e.fillInStackTrace();
16384            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16385        }
16386
16387        mAdjSeq++;
16388        mNewNumServiceProcs = 0;
16389        mNewNumAServiceProcs = 0;
16390
16391        final int emptyProcessLimit;
16392        final int cachedProcessLimit;
16393        if (mProcessLimit <= 0) {
16394            emptyProcessLimit = cachedProcessLimit = 0;
16395        } else if (mProcessLimit == 1) {
16396            emptyProcessLimit = 1;
16397            cachedProcessLimit = 0;
16398        } else {
16399            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16400            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16401        }
16402
16403        // Let's determine how many processes we have running vs.
16404        // how many slots we have for background processes; we may want
16405        // to put multiple processes in a slot of there are enough of
16406        // them.
16407        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16408                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16409        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16410        if (numEmptyProcs > cachedProcessLimit) {
16411            // If there are more empty processes than our limit on cached
16412            // processes, then use the cached process limit for the factor.
16413            // This ensures that the really old empty processes get pushed
16414            // down to the bottom, so if we are running low on memory we will
16415            // have a better chance at keeping around more cached processes
16416            // instead of a gazillion empty processes.
16417            numEmptyProcs = cachedProcessLimit;
16418        }
16419        int emptyFactor = numEmptyProcs/numSlots;
16420        if (emptyFactor < 1) emptyFactor = 1;
16421        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16422        if (cachedFactor < 1) cachedFactor = 1;
16423        int stepCached = 0;
16424        int stepEmpty = 0;
16425        int numCached = 0;
16426        int numEmpty = 0;
16427        int numTrimming = 0;
16428
16429        mNumNonCachedProcs = 0;
16430        mNumCachedHiddenProcs = 0;
16431
16432        // First update the OOM adjustment for each of the
16433        // application processes based on their current state.
16434        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16435        int nextCachedAdj = curCachedAdj+1;
16436        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16437        int nextEmptyAdj = curEmptyAdj+2;
16438        for (int i=N-1; i>=0; i--) {
16439            ProcessRecord app = mLruProcesses.get(i);
16440            if (!app.killedByAm && app.thread != null) {
16441                app.procStateChanged = false;
16442                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16443
16444                // If we haven't yet assigned the final cached adj
16445                // to the process, do that now.
16446                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16447                    switch (app.curProcState) {
16448                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16449                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16450                            // This process is a cached process holding activities...
16451                            // assign it the next cached value for that type, and then
16452                            // step that cached level.
16453                            app.curRawAdj = curCachedAdj;
16454                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16455                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16456                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16457                                    + ")");
16458                            if (curCachedAdj != nextCachedAdj) {
16459                                stepCached++;
16460                                if (stepCached >= cachedFactor) {
16461                                    stepCached = 0;
16462                                    curCachedAdj = nextCachedAdj;
16463                                    nextCachedAdj += 2;
16464                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16465                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16466                                    }
16467                                }
16468                            }
16469                            break;
16470                        default:
16471                            // For everything else, assign next empty cached process
16472                            // level and bump that up.  Note that this means that
16473                            // long-running services that have dropped down to the
16474                            // cached level will be treated as empty (since their process
16475                            // state is still as a service), which is what we want.
16476                            app.curRawAdj = curEmptyAdj;
16477                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16478                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16479                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16480                                    + ")");
16481                            if (curEmptyAdj != nextEmptyAdj) {
16482                                stepEmpty++;
16483                                if (stepEmpty >= emptyFactor) {
16484                                    stepEmpty = 0;
16485                                    curEmptyAdj = nextEmptyAdj;
16486                                    nextEmptyAdj += 2;
16487                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16488                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16489                                    }
16490                                }
16491                            }
16492                            break;
16493                    }
16494                }
16495
16496                applyOomAdjLocked(app, TOP_APP, true, now);
16497
16498                // Count the number of process types.
16499                switch (app.curProcState) {
16500                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16501                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16502                        mNumCachedHiddenProcs++;
16503                        numCached++;
16504                        if (numCached > cachedProcessLimit) {
16505                            killUnneededProcessLocked(app, "cached #" + numCached);
16506                        }
16507                        break;
16508                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16509                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16510                                && app.lastActivityTime < oldTime) {
16511                            killUnneededProcessLocked(app, "empty for "
16512                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16513                                    / 1000) + "s");
16514                        } else {
16515                            numEmpty++;
16516                            if (numEmpty > emptyProcessLimit) {
16517                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16518                            }
16519                        }
16520                        break;
16521                    default:
16522                        mNumNonCachedProcs++;
16523                        break;
16524                }
16525
16526                if (app.isolated && app.services.size() <= 0) {
16527                    // If this is an isolated process, and there are no
16528                    // services running in it, then the process is no longer
16529                    // needed.  We agressively kill these because we can by
16530                    // definition not re-use the same process again, and it is
16531                    // good to avoid having whatever code was running in them
16532                    // left sitting around after no longer needed.
16533                    killUnneededProcessLocked(app, "isolated not needed");
16534                }
16535
16536                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16537                        && !app.killedByAm) {
16538                    numTrimming++;
16539                }
16540            }
16541        }
16542
16543        mNumServiceProcs = mNewNumServiceProcs;
16544
16545        // Now determine the memory trimming level of background processes.
16546        // Unfortunately we need to start at the back of the list to do this
16547        // properly.  We only do this if the number of background apps we
16548        // are managing to keep around is less than half the maximum we desire;
16549        // if we are keeping a good number around, we'll let them use whatever
16550        // memory they want.
16551        final int numCachedAndEmpty = numCached + numEmpty;
16552        int memFactor;
16553        if (numCached <= ProcessList.TRIM_CACHED_APPS
16554                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16555            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16556                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16557            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16558                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16559            } else {
16560                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16561            }
16562        } else {
16563            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16564        }
16565        // We always allow the memory level to go up (better).  We only allow it to go
16566        // down if we are in a state where that is allowed, *and* the total number of processes
16567        // has gone down since last time.
16568        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16569                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16570                + " last=" + mLastNumProcesses);
16571        if (memFactor > mLastMemoryLevel) {
16572            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16573                memFactor = mLastMemoryLevel;
16574                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16575            }
16576        }
16577        mLastMemoryLevel = memFactor;
16578        mLastNumProcesses = mLruProcesses.size();
16579        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16580        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16581        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16582            if (mLowRamStartTime == 0) {
16583                mLowRamStartTime = now;
16584            }
16585            int step = 0;
16586            int fgTrimLevel;
16587            switch (memFactor) {
16588                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16589                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16590                    break;
16591                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16592                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16593                    break;
16594                default:
16595                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16596                    break;
16597            }
16598            int factor = numTrimming/3;
16599            int minFactor = 2;
16600            if (mHomeProcess != null) minFactor++;
16601            if (mPreviousProcess != null) minFactor++;
16602            if (factor < minFactor) factor = minFactor;
16603            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16604            for (int i=N-1; i>=0; i--) {
16605                ProcessRecord app = mLruProcesses.get(i);
16606                if (allChanged || app.procStateChanged) {
16607                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16608                    app.procStateChanged = false;
16609                }
16610                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16611                        && !app.killedByAm) {
16612                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16613                        try {
16614                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16615                                    "Trimming memory of " + app.processName
16616                                    + " to " + curLevel);
16617                            app.thread.scheduleTrimMemory(curLevel);
16618                        } catch (RemoteException e) {
16619                        }
16620                        if (false) {
16621                            // For now we won't do this; our memory trimming seems
16622                            // to be good enough at this point that destroying
16623                            // activities causes more harm than good.
16624                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16625                                    && app != mHomeProcess && app != mPreviousProcess) {
16626                                // Need to do this on its own message because the stack may not
16627                                // be in a consistent state at this point.
16628                                // For these apps we will also finish their activities
16629                                // to help them free memory.
16630                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16631                            }
16632                        }
16633                    }
16634                    app.trimMemoryLevel = curLevel;
16635                    step++;
16636                    if (step >= factor) {
16637                        step = 0;
16638                        switch (curLevel) {
16639                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16640                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16641                                break;
16642                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16643                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16644                                break;
16645                        }
16646                    }
16647                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16648                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16649                            && app.thread != null) {
16650                        try {
16651                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16652                                    "Trimming memory of heavy-weight " + app.processName
16653                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16654                            app.thread.scheduleTrimMemory(
16655                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16656                        } catch (RemoteException e) {
16657                        }
16658                    }
16659                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16660                } else {
16661                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16662                            || app.systemNoUi) && app.pendingUiClean) {
16663                        // If this application is now in the background and it
16664                        // had done UI, then give it the special trim level to
16665                        // have it free UI resources.
16666                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16667                        if (app.trimMemoryLevel < level && app.thread != null) {
16668                            try {
16669                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16670                                        "Trimming memory of bg-ui " + app.processName
16671                                        + " to " + level);
16672                                app.thread.scheduleTrimMemory(level);
16673                            } catch (RemoteException e) {
16674                            }
16675                        }
16676                        app.pendingUiClean = false;
16677                    }
16678                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16679                        try {
16680                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16681                                    "Trimming memory of fg " + app.processName
16682                                    + " to " + fgTrimLevel);
16683                            app.thread.scheduleTrimMemory(fgTrimLevel);
16684                        } catch (RemoteException e) {
16685                        }
16686                    }
16687                    app.trimMemoryLevel = fgTrimLevel;
16688                }
16689            }
16690        } else {
16691            if (mLowRamStartTime != 0) {
16692                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16693                mLowRamStartTime = 0;
16694            }
16695            for (int i=N-1; i>=0; i--) {
16696                ProcessRecord app = mLruProcesses.get(i);
16697                if (allChanged || app.procStateChanged) {
16698                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16699                    app.procStateChanged = false;
16700                }
16701                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16702                        || app.systemNoUi) && app.pendingUiClean) {
16703                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16704                            && app.thread != null) {
16705                        try {
16706                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16707                                    "Trimming memory of ui hidden " + app.processName
16708                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16709                            app.thread.scheduleTrimMemory(
16710                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16711                        } catch (RemoteException e) {
16712                        }
16713                    }
16714                    app.pendingUiClean = false;
16715                }
16716                app.trimMemoryLevel = 0;
16717            }
16718        }
16719
16720        if (mAlwaysFinishActivities) {
16721            // Need to do this on its own message because the stack may not
16722            // be in a consistent state at this point.
16723            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16724        }
16725
16726        if (allChanged) {
16727            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16728        }
16729
16730        if (mProcessStats.shouldWriteNowLocked(now)) {
16731            mHandler.post(new Runnable() {
16732                @Override public void run() {
16733                    synchronized (ActivityManagerService.this) {
16734                        mProcessStats.writeStateAsyncLocked();
16735                    }
16736                }
16737            });
16738        }
16739
16740        if (DEBUG_OOM_ADJ) {
16741            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16742        }
16743    }
16744
16745    final void trimApplications() {
16746        synchronized (this) {
16747            int i;
16748
16749            // First remove any unused application processes whose package
16750            // has been removed.
16751            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16752                final ProcessRecord app = mRemovedProcesses.get(i);
16753                if (app.activities.size() == 0
16754                        && app.curReceiver == null && app.services.size() == 0) {
16755                    Slog.i(
16756                        TAG, "Exiting empty application process "
16757                        + app.processName + " ("
16758                        + (app.thread != null ? app.thread.asBinder() : null)
16759                        + ")\n");
16760                    if (app.pid > 0 && app.pid != MY_PID) {
16761                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16762                                app.processName, app.setAdj, "empty");
16763                        app.killedByAm = true;
16764                        Process.killProcessQuiet(app.pid);
16765                        Process.killProcessGroup(app.info.uid, app.pid);
16766                    } else {
16767                        try {
16768                            app.thread.scheduleExit();
16769                        } catch (Exception e) {
16770                            // Ignore exceptions.
16771                        }
16772                    }
16773                    cleanUpApplicationRecordLocked(app, false, true, -1);
16774                    mRemovedProcesses.remove(i);
16775
16776                    if (app.persistent) {
16777                        addAppLocked(app.info, false, null /* ABI override */);
16778                    }
16779                }
16780            }
16781
16782            // Now update the oom adj for all processes.
16783            updateOomAdjLocked();
16784        }
16785    }
16786
16787    /** This method sends the specified signal to each of the persistent apps */
16788    public void signalPersistentProcesses(int sig) throws RemoteException {
16789        if (sig != Process.SIGNAL_USR1) {
16790            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16791        }
16792
16793        synchronized (this) {
16794            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16795                    != PackageManager.PERMISSION_GRANTED) {
16796                throw new SecurityException("Requires permission "
16797                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16798            }
16799
16800            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16801                ProcessRecord r = mLruProcesses.get(i);
16802                if (r.thread != null && r.persistent) {
16803                    Process.sendSignal(r.pid, sig);
16804                }
16805            }
16806        }
16807    }
16808
16809    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16810        if (proc == null || proc == mProfileProc) {
16811            proc = mProfileProc;
16812            path = mProfileFile;
16813            profileType = mProfileType;
16814            clearProfilerLocked();
16815        }
16816        if (proc == null) {
16817            return;
16818        }
16819        try {
16820            proc.thread.profilerControl(false, path, null, profileType);
16821        } catch (RemoteException e) {
16822            throw new IllegalStateException("Process disappeared");
16823        }
16824    }
16825
16826    private void clearProfilerLocked() {
16827        if (mProfileFd != null) {
16828            try {
16829                mProfileFd.close();
16830            } catch (IOException e) {
16831            }
16832        }
16833        mProfileApp = null;
16834        mProfileProc = null;
16835        mProfileFile = null;
16836        mProfileType = 0;
16837        mAutoStopProfiler = false;
16838    }
16839
16840    public boolean profileControl(String process, int userId, boolean start,
16841            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16842
16843        try {
16844            synchronized (this) {
16845                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16846                // its own permission.
16847                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16848                        != PackageManager.PERMISSION_GRANTED) {
16849                    throw new SecurityException("Requires permission "
16850                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16851                }
16852
16853                if (start && fd == null) {
16854                    throw new IllegalArgumentException("null fd");
16855                }
16856
16857                ProcessRecord proc = null;
16858                if (process != null) {
16859                    proc = findProcessLocked(process, userId, "profileControl");
16860                }
16861
16862                if (start && (proc == null || proc.thread == null)) {
16863                    throw new IllegalArgumentException("Unknown process: " + process);
16864                }
16865
16866                if (start) {
16867                    stopProfilerLocked(null, null, 0);
16868                    setProfileApp(proc.info, proc.processName, path, fd, false);
16869                    mProfileProc = proc;
16870                    mProfileType = profileType;
16871                    try {
16872                        fd = fd.dup();
16873                    } catch (IOException e) {
16874                        fd = null;
16875                    }
16876                    proc.thread.profilerControl(start, path, fd, profileType);
16877                    fd = null;
16878                    mProfileFd = null;
16879                } else {
16880                    stopProfilerLocked(proc, path, profileType);
16881                    if (fd != null) {
16882                        try {
16883                            fd.close();
16884                        } catch (IOException e) {
16885                        }
16886                    }
16887                }
16888
16889                return true;
16890            }
16891        } catch (RemoteException e) {
16892            throw new IllegalStateException("Process disappeared");
16893        } finally {
16894            if (fd != null) {
16895                try {
16896                    fd.close();
16897                } catch (IOException e) {
16898                }
16899            }
16900        }
16901    }
16902
16903    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16904        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16905                userId, true, ALLOW_FULL_ONLY, callName, null);
16906        ProcessRecord proc = null;
16907        try {
16908            int pid = Integer.parseInt(process);
16909            synchronized (mPidsSelfLocked) {
16910                proc = mPidsSelfLocked.get(pid);
16911            }
16912        } catch (NumberFormatException e) {
16913        }
16914
16915        if (proc == null) {
16916            ArrayMap<String, SparseArray<ProcessRecord>> all
16917                    = mProcessNames.getMap();
16918            SparseArray<ProcessRecord> procs = all.get(process);
16919            if (procs != null && procs.size() > 0) {
16920                proc = procs.valueAt(0);
16921                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16922                    for (int i=1; i<procs.size(); i++) {
16923                        ProcessRecord thisProc = procs.valueAt(i);
16924                        if (thisProc.userId == userId) {
16925                            proc = thisProc;
16926                            break;
16927                        }
16928                    }
16929                }
16930            }
16931        }
16932
16933        return proc;
16934    }
16935
16936    public boolean dumpHeap(String process, int userId, boolean managed,
16937            String path, ParcelFileDescriptor fd) throws RemoteException {
16938
16939        try {
16940            synchronized (this) {
16941                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16942                // its own permission (same as profileControl).
16943                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16944                        != PackageManager.PERMISSION_GRANTED) {
16945                    throw new SecurityException("Requires permission "
16946                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16947                }
16948
16949                if (fd == null) {
16950                    throw new IllegalArgumentException("null fd");
16951                }
16952
16953                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16954                if (proc == null || proc.thread == null) {
16955                    throw new IllegalArgumentException("Unknown process: " + process);
16956                }
16957
16958                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16959                if (!isDebuggable) {
16960                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16961                        throw new SecurityException("Process not debuggable: " + proc);
16962                    }
16963                }
16964
16965                proc.thread.dumpHeap(managed, path, fd);
16966                fd = null;
16967                return true;
16968            }
16969        } catch (RemoteException e) {
16970            throw new IllegalStateException("Process disappeared");
16971        } finally {
16972            if (fd != null) {
16973                try {
16974                    fd.close();
16975                } catch (IOException e) {
16976                }
16977            }
16978        }
16979    }
16980
16981    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16982    public void monitor() {
16983        synchronized (this) { }
16984    }
16985
16986    void onCoreSettingsChange(Bundle settings) {
16987        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16988            ProcessRecord processRecord = mLruProcesses.get(i);
16989            try {
16990                if (processRecord.thread != null) {
16991                    processRecord.thread.setCoreSettings(settings);
16992                }
16993            } catch (RemoteException re) {
16994                /* ignore */
16995            }
16996        }
16997    }
16998
16999    // Multi-user methods
17000
17001    /**
17002     * Start user, if its not already running, but don't bring it to foreground.
17003     */
17004    @Override
17005    public boolean startUserInBackground(final int userId) {
17006        return startUser(userId, /* foreground */ false);
17007    }
17008
17009    /**
17010     * Refreshes the list of users related to the current user when either a
17011     * user switch happens or when a new related user is started in the
17012     * background.
17013     */
17014    private void updateCurrentProfileIdsLocked() {
17015        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17016                mCurrentUserId, false /* enabledOnly */);
17017        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17018        for (int i = 0; i < currentProfileIds.length; i++) {
17019            currentProfileIds[i] = profiles.get(i).id;
17020        }
17021        mCurrentProfileIds = currentProfileIds;
17022
17023        synchronized (mUserProfileGroupIdsSelfLocked) {
17024            mUserProfileGroupIdsSelfLocked.clear();
17025            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17026            for (int i = 0; i < users.size(); i++) {
17027                UserInfo user = users.get(i);
17028                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17029                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17030                }
17031            }
17032        }
17033    }
17034
17035    private Set getProfileIdsLocked(int userId) {
17036        Set userIds = new HashSet<Integer>();
17037        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17038                userId, false /* enabledOnly */);
17039        for (UserInfo user : profiles) {
17040            userIds.add(Integer.valueOf(user.id));
17041        }
17042        return userIds;
17043    }
17044
17045    @Override
17046    public boolean switchUser(final int userId) {
17047        return startUser(userId, /* foregound */ true);
17048    }
17049
17050    private boolean startUser(final int userId, boolean foreground) {
17051        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17052                != PackageManager.PERMISSION_GRANTED) {
17053            String msg = "Permission Denial: switchUser() from pid="
17054                    + Binder.getCallingPid()
17055                    + ", uid=" + Binder.getCallingUid()
17056                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17057            Slog.w(TAG, msg);
17058            throw new SecurityException(msg);
17059        }
17060
17061        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17062
17063        final long ident = Binder.clearCallingIdentity();
17064        try {
17065            synchronized (this) {
17066                final int oldUserId = mCurrentUserId;
17067                if (oldUserId == userId) {
17068                    return true;
17069                }
17070
17071                mStackSupervisor.setLockTaskModeLocked(null, false);
17072
17073                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17074                if (userInfo == null) {
17075                    Slog.w(TAG, "No user info for user #" + userId);
17076                    return false;
17077                }
17078
17079                if (foreground) {
17080                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17081                            R.anim.screen_user_enter);
17082                }
17083
17084                boolean needStart = false;
17085
17086                // If the user we are switching to is not currently started, then
17087                // we need to start it now.
17088                if (mStartedUsers.get(userId) == null) {
17089                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17090                    updateStartedUserArrayLocked();
17091                    needStart = true;
17092                }
17093
17094                final Integer userIdInt = Integer.valueOf(userId);
17095                mUserLru.remove(userIdInt);
17096                mUserLru.add(userIdInt);
17097
17098                if (foreground) {
17099                    mCurrentUserId = userId;
17100                    updateCurrentProfileIdsLocked();
17101                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17102                    // Once the internal notion of the active user has switched, we lock the device
17103                    // with the option to show the user switcher on the keyguard.
17104                    mWindowManager.lockNow(null);
17105                } else {
17106                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17107                    updateCurrentProfileIdsLocked();
17108                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17109                    mUserLru.remove(currentUserIdInt);
17110                    mUserLru.add(currentUserIdInt);
17111                }
17112
17113                final UserStartedState uss = mStartedUsers.get(userId);
17114
17115                // Make sure user is in the started state.  If it is currently
17116                // stopping, we need to knock that off.
17117                if (uss.mState == UserStartedState.STATE_STOPPING) {
17118                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17119                    // so we can just fairly silently bring the user back from
17120                    // the almost-dead.
17121                    uss.mState = UserStartedState.STATE_RUNNING;
17122                    updateStartedUserArrayLocked();
17123                    needStart = true;
17124                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17125                    // This means ACTION_SHUTDOWN has been sent, so we will
17126                    // need to treat this as a new boot of the user.
17127                    uss.mState = UserStartedState.STATE_BOOTING;
17128                    updateStartedUserArrayLocked();
17129                    needStart = true;
17130                }
17131
17132                if (uss.mState == UserStartedState.STATE_BOOTING) {
17133                    // Booting up a new user, need to tell system services about it.
17134                    // Note that this is on the same handler as scheduling of broadcasts,
17135                    // which is important because it needs to go first.
17136                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17137                }
17138
17139                if (foreground) {
17140                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17141                            oldUserId));
17142                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17143                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17144                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17145                            oldUserId, userId, uss));
17146                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17147                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17148                }
17149
17150                if (needStart) {
17151                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17152                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17153                            | Intent.FLAG_RECEIVER_FOREGROUND);
17154                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17155                    broadcastIntentLocked(null, null, intent,
17156                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17157                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17158                }
17159
17160                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17161                    if (userId != UserHandle.USER_OWNER) {
17162                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17163                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17164                        broadcastIntentLocked(null, null, intent, null,
17165                                new IIntentReceiver.Stub() {
17166                                    public void performReceive(Intent intent, int resultCode,
17167                                            String data, Bundle extras, boolean ordered,
17168                                            boolean sticky, int sendingUser) {
17169                                        userInitialized(uss, userId);
17170                                    }
17171                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17172                                true, false, MY_PID, Process.SYSTEM_UID,
17173                                userId);
17174                        uss.initializing = true;
17175                    } else {
17176                        getUserManagerLocked().makeInitialized(userInfo.id);
17177                    }
17178                }
17179
17180                if (foreground) {
17181                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17182                    if (homeInFront) {
17183                        startHomeActivityLocked(userId);
17184                    } else {
17185                        mStackSupervisor.resumeTopActivitiesLocked();
17186                    }
17187                    EventLogTags.writeAmSwitchUser(userId);
17188                    getUserManagerLocked().userForeground(userId);
17189                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17190                } else {
17191                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17192                }
17193
17194                if (needStart) {
17195                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17196                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17197                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17198                    broadcastIntentLocked(null, null, intent,
17199                            null, new IIntentReceiver.Stub() {
17200                                @Override
17201                                public void performReceive(Intent intent, int resultCode, String data,
17202                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17203                                        throws RemoteException {
17204                                }
17205                            }, 0, null, null,
17206                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17207                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17208                }
17209            }
17210        } finally {
17211            Binder.restoreCallingIdentity(ident);
17212        }
17213
17214        return true;
17215    }
17216
17217    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17218        long ident = Binder.clearCallingIdentity();
17219        try {
17220            Intent intent;
17221            if (oldUserId >= 0) {
17222                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17223                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17224                int count = profiles.size();
17225                for (int i = 0; i < count; i++) {
17226                    int profileUserId = profiles.get(i).id;
17227                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17228                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17229                            | Intent.FLAG_RECEIVER_FOREGROUND);
17230                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17231                    broadcastIntentLocked(null, null, intent,
17232                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17233                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17234                }
17235            }
17236            if (newUserId >= 0) {
17237                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17238                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17239                int count = profiles.size();
17240                for (int i = 0; i < count; i++) {
17241                    int profileUserId = profiles.get(i).id;
17242                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17243                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17244                            | Intent.FLAG_RECEIVER_FOREGROUND);
17245                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17246                    broadcastIntentLocked(null, null, intent,
17247                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17248                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17249                }
17250                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17251                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17252                        | Intent.FLAG_RECEIVER_FOREGROUND);
17253                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17254                broadcastIntentLocked(null, null, intent,
17255                        null, null, 0, null, null,
17256                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17257                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17258            }
17259        } finally {
17260            Binder.restoreCallingIdentity(ident);
17261        }
17262    }
17263
17264    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17265            final int newUserId) {
17266        final int N = mUserSwitchObservers.beginBroadcast();
17267        if (N > 0) {
17268            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17269                int mCount = 0;
17270                @Override
17271                public void sendResult(Bundle data) throws RemoteException {
17272                    synchronized (ActivityManagerService.this) {
17273                        if (mCurUserSwitchCallback == this) {
17274                            mCount++;
17275                            if (mCount == N) {
17276                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17277                            }
17278                        }
17279                    }
17280                }
17281            };
17282            synchronized (this) {
17283                uss.switching = true;
17284                mCurUserSwitchCallback = callback;
17285            }
17286            for (int i=0; i<N; i++) {
17287                try {
17288                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17289                            newUserId, callback);
17290                } catch (RemoteException e) {
17291                }
17292            }
17293        } else {
17294            synchronized (this) {
17295                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17296            }
17297        }
17298        mUserSwitchObservers.finishBroadcast();
17299    }
17300
17301    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17302        synchronized (this) {
17303            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17304            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17305        }
17306    }
17307
17308    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17309        mCurUserSwitchCallback = null;
17310        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17311        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17312                oldUserId, newUserId, uss));
17313    }
17314
17315    void userInitialized(UserStartedState uss, int newUserId) {
17316        completeSwitchAndInitalize(uss, newUserId, true, false);
17317    }
17318
17319    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17320        completeSwitchAndInitalize(uss, newUserId, false, true);
17321    }
17322
17323    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17324            boolean clearInitializing, boolean clearSwitching) {
17325        boolean unfrozen = false;
17326        synchronized (this) {
17327            if (clearInitializing) {
17328                uss.initializing = false;
17329                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17330            }
17331            if (clearSwitching) {
17332                uss.switching = false;
17333            }
17334            if (!uss.switching && !uss.initializing) {
17335                mWindowManager.stopFreezingScreen();
17336                unfrozen = true;
17337            }
17338        }
17339        if (unfrozen) {
17340            final int N = mUserSwitchObservers.beginBroadcast();
17341            for (int i=0; i<N; i++) {
17342                try {
17343                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17344                } catch (RemoteException e) {
17345                }
17346            }
17347            mUserSwitchObservers.finishBroadcast();
17348        }
17349    }
17350
17351    void scheduleStartProfilesLocked() {
17352        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17353            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17354                    DateUtils.SECOND_IN_MILLIS);
17355        }
17356    }
17357
17358    void startProfilesLocked() {
17359        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17360        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17361                mCurrentUserId, false /* enabledOnly */);
17362        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17363        for (UserInfo user : profiles) {
17364            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17365                    && user.id != mCurrentUserId) {
17366                toStart.add(user);
17367            }
17368        }
17369        final int n = toStart.size();
17370        int i = 0;
17371        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17372            startUserInBackground(toStart.get(i).id);
17373        }
17374        if (i < n) {
17375            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17376        }
17377    }
17378
17379    void finishUserBoot(UserStartedState uss) {
17380        synchronized (this) {
17381            if (uss.mState == UserStartedState.STATE_BOOTING
17382                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17383                uss.mState = UserStartedState.STATE_RUNNING;
17384                final int userId = uss.mHandle.getIdentifier();
17385                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17386                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17387                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17388                broadcastIntentLocked(null, null, intent,
17389                        null, null, 0, null, null,
17390                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17391                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17392            }
17393        }
17394    }
17395
17396    void finishUserSwitch(UserStartedState uss) {
17397        synchronized (this) {
17398            finishUserBoot(uss);
17399
17400            startProfilesLocked();
17401
17402            int num = mUserLru.size();
17403            int i = 0;
17404            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17405                Integer oldUserId = mUserLru.get(i);
17406                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17407                if (oldUss == null) {
17408                    // Shouldn't happen, but be sane if it does.
17409                    mUserLru.remove(i);
17410                    num--;
17411                    continue;
17412                }
17413                if (oldUss.mState == UserStartedState.STATE_STOPPING
17414                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17415                    // This user is already stopping, doesn't count.
17416                    num--;
17417                    i++;
17418                    continue;
17419                }
17420                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17421                    // Owner and current can't be stopped, but count as running.
17422                    i++;
17423                    continue;
17424                }
17425                // This is a user to be stopped.
17426                stopUserLocked(oldUserId, null);
17427                num--;
17428                i++;
17429            }
17430        }
17431    }
17432
17433    @Override
17434    public int stopUser(final int userId, final IStopUserCallback callback) {
17435        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17436                != PackageManager.PERMISSION_GRANTED) {
17437            String msg = "Permission Denial: switchUser() from pid="
17438                    + Binder.getCallingPid()
17439                    + ", uid=" + Binder.getCallingUid()
17440                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17441            Slog.w(TAG, msg);
17442            throw new SecurityException(msg);
17443        }
17444        if (userId <= 0) {
17445            throw new IllegalArgumentException("Can't stop primary user " + userId);
17446        }
17447        synchronized (this) {
17448            return stopUserLocked(userId, callback);
17449        }
17450    }
17451
17452    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17453        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17454        if (mCurrentUserId == userId) {
17455            return ActivityManager.USER_OP_IS_CURRENT;
17456        }
17457
17458        final UserStartedState uss = mStartedUsers.get(userId);
17459        if (uss == null) {
17460            // User is not started, nothing to do...  but we do need to
17461            // callback if requested.
17462            if (callback != null) {
17463                mHandler.post(new Runnable() {
17464                    @Override
17465                    public void run() {
17466                        try {
17467                            callback.userStopped(userId);
17468                        } catch (RemoteException e) {
17469                        }
17470                    }
17471                });
17472            }
17473            return ActivityManager.USER_OP_SUCCESS;
17474        }
17475
17476        if (callback != null) {
17477            uss.mStopCallbacks.add(callback);
17478        }
17479
17480        if (uss.mState != UserStartedState.STATE_STOPPING
17481                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17482            uss.mState = UserStartedState.STATE_STOPPING;
17483            updateStartedUserArrayLocked();
17484
17485            long ident = Binder.clearCallingIdentity();
17486            try {
17487                // We are going to broadcast ACTION_USER_STOPPING and then
17488                // once that is done send a final ACTION_SHUTDOWN and then
17489                // stop the user.
17490                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17491                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17492                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17493                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17494                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17495                // This is the result receiver for the final shutdown broadcast.
17496                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17497                    @Override
17498                    public void performReceive(Intent intent, int resultCode, String data,
17499                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17500                        finishUserStop(uss);
17501                    }
17502                };
17503                // This is the result receiver for the initial stopping broadcast.
17504                final IIntentReceiver stoppingReceiver = 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                        // On to the next.
17509                        synchronized (ActivityManagerService.this) {
17510                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17511                                // Whoops, we are being started back up.  Abort, abort!
17512                                return;
17513                            }
17514                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17515                        }
17516                        mBatteryStatsService.noteEvent(
17517                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17518                                Integer.toString(userId), userId);
17519                        mSystemServiceManager.stopUser(userId);
17520                        broadcastIntentLocked(null, null, shutdownIntent,
17521                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17522                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17523                    }
17524                };
17525                // Kick things off.
17526                broadcastIntentLocked(null, null, stoppingIntent,
17527                        null, stoppingReceiver, 0, null, null,
17528                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17529                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17530            } finally {
17531                Binder.restoreCallingIdentity(ident);
17532            }
17533        }
17534
17535        return ActivityManager.USER_OP_SUCCESS;
17536    }
17537
17538    void finishUserStop(UserStartedState uss) {
17539        final int userId = uss.mHandle.getIdentifier();
17540        boolean stopped;
17541        ArrayList<IStopUserCallback> callbacks;
17542        synchronized (this) {
17543            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17544            if (mStartedUsers.get(userId) != uss) {
17545                stopped = false;
17546            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17547                stopped = false;
17548            } else {
17549                stopped = true;
17550                // User can no longer run.
17551                mStartedUsers.remove(userId);
17552                mUserLru.remove(Integer.valueOf(userId));
17553                updateStartedUserArrayLocked();
17554
17555                // Clean up all state and processes associated with the user.
17556                // Kill all the processes for the user.
17557                forceStopUserLocked(userId, "finish user");
17558            }
17559        }
17560
17561        for (int i=0; i<callbacks.size(); i++) {
17562            try {
17563                if (stopped) callbacks.get(i).userStopped(userId);
17564                else callbacks.get(i).userStopAborted(userId);
17565            } catch (RemoteException e) {
17566            }
17567        }
17568
17569        if (stopped) {
17570            mSystemServiceManager.cleanupUser(userId);
17571            synchronized (this) {
17572                mStackSupervisor.removeUserLocked(userId);
17573            }
17574        }
17575    }
17576
17577    @Override
17578    public UserInfo getCurrentUser() {
17579        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17580                != PackageManager.PERMISSION_GRANTED) && (
17581                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17582                != PackageManager.PERMISSION_GRANTED)) {
17583            String msg = "Permission Denial: getCurrentUser() from pid="
17584                    + Binder.getCallingPid()
17585                    + ", uid=" + Binder.getCallingUid()
17586                    + " requires " + INTERACT_ACROSS_USERS;
17587            Slog.w(TAG, msg);
17588            throw new SecurityException(msg);
17589        }
17590        synchronized (this) {
17591            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17592        }
17593    }
17594
17595    int getCurrentUserIdLocked() {
17596        return mCurrentUserId;
17597    }
17598
17599    @Override
17600    public boolean isUserRunning(int userId, boolean orStopped) {
17601        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17602                != PackageManager.PERMISSION_GRANTED) {
17603            String msg = "Permission Denial: isUserRunning() from pid="
17604                    + Binder.getCallingPid()
17605                    + ", uid=" + Binder.getCallingUid()
17606                    + " requires " + INTERACT_ACROSS_USERS;
17607            Slog.w(TAG, msg);
17608            throw new SecurityException(msg);
17609        }
17610        synchronized (this) {
17611            return isUserRunningLocked(userId, orStopped);
17612        }
17613    }
17614
17615    boolean isUserRunningLocked(int userId, boolean orStopped) {
17616        UserStartedState state = mStartedUsers.get(userId);
17617        if (state == null) {
17618            return false;
17619        }
17620        if (orStopped) {
17621            return true;
17622        }
17623        return state.mState != UserStartedState.STATE_STOPPING
17624                && state.mState != UserStartedState.STATE_SHUTDOWN;
17625    }
17626
17627    @Override
17628    public int[] getRunningUserIds() {
17629        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17630                != PackageManager.PERMISSION_GRANTED) {
17631            String msg = "Permission Denial: isUserRunning() from pid="
17632                    + Binder.getCallingPid()
17633                    + ", uid=" + Binder.getCallingUid()
17634                    + " requires " + INTERACT_ACROSS_USERS;
17635            Slog.w(TAG, msg);
17636            throw new SecurityException(msg);
17637        }
17638        synchronized (this) {
17639            return mStartedUserArray;
17640        }
17641    }
17642
17643    private void updateStartedUserArrayLocked() {
17644        int num = 0;
17645        for (int i=0; i<mStartedUsers.size();  i++) {
17646            UserStartedState uss = mStartedUsers.valueAt(i);
17647            // This list does not include stopping users.
17648            if (uss.mState != UserStartedState.STATE_STOPPING
17649                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17650                num++;
17651            }
17652        }
17653        mStartedUserArray = new int[num];
17654        num = 0;
17655        for (int i=0; i<mStartedUsers.size();  i++) {
17656            UserStartedState uss = mStartedUsers.valueAt(i);
17657            if (uss.mState != UserStartedState.STATE_STOPPING
17658                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17659                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17660                num++;
17661            }
17662        }
17663    }
17664
17665    @Override
17666    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17667        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17668                != PackageManager.PERMISSION_GRANTED) {
17669            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17670                    + Binder.getCallingPid()
17671                    + ", uid=" + Binder.getCallingUid()
17672                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17673            Slog.w(TAG, msg);
17674            throw new SecurityException(msg);
17675        }
17676
17677        mUserSwitchObservers.register(observer);
17678    }
17679
17680    @Override
17681    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17682        mUserSwitchObservers.unregister(observer);
17683    }
17684
17685    private boolean userExists(int userId) {
17686        if (userId == 0) {
17687            return true;
17688        }
17689        UserManagerService ums = getUserManagerLocked();
17690        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17691    }
17692
17693    int[] getUsersLocked() {
17694        UserManagerService ums = getUserManagerLocked();
17695        return ums != null ? ums.getUserIds() : new int[] { 0 };
17696    }
17697
17698    UserManagerService getUserManagerLocked() {
17699        if (mUserManager == null) {
17700            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17701            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17702        }
17703        return mUserManager;
17704    }
17705
17706    private int applyUserId(int uid, int userId) {
17707        return UserHandle.getUid(userId, uid);
17708    }
17709
17710    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17711        if (info == null) return null;
17712        ApplicationInfo newInfo = new ApplicationInfo(info);
17713        newInfo.uid = applyUserId(info.uid, userId);
17714        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17715                + info.packageName;
17716        return newInfo;
17717    }
17718
17719    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17720        if (aInfo == null
17721                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17722            return aInfo;
17723        }
17724
17725        ActivityInfo info = new ActivityInfo(aInfo);
17726        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17727        return info;
17728    }
17729
17730    private final class LocalService extends ActivityManagerInternal {
17731        @Override
17732        public void goingToSleep() {
17733            ActivityManagerService.this.goingToSleep();
17734        }
17735
17736        @Override
17737        public void wakingUp() {
17738            ActivityManagerService.this.wakingUp();
17739        }
17740    }
17741
17742    /**
17743     * An implementation of IAppTask, that allows an app to manage its own tasks via
17744     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17745     * only the process that calls getAppTasks() can call the AppTask methods.
17746     */
17747    class AppTaskImpl extends IAppTask.Stub {
17748        private int mTaskId;
17749        private int mCallingUid;
17750
17751        public AppTaskImpl(int taskId, int callingUid) {
17752            mTaskId = taskId;
17753            mCallingUid = callingUid;
17754        }
17755
17756        @Override
17757        public void finishAndRemoveTask() {
17758            // Ensure that we are called from the same process that created this AppTask
17759            if (mCallingUid != Binder.getCallingUid()) {
17760                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17761                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17762                return;
17763            }
17764
17765            synchronized (ActivityManagerService.this) {
17766                long origId = Binder.clearCallingIdentity();
17767                try {
17768                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17769                    if (tr != null) {
17770                        // Only kill the process if we are not a new document
17771                        int flags = tr.getBaseIntent().getFlags();
17772                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17773                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17774                        removeTaskByIdLocked(mTaskId,
17775                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17776                    }
17777                } finally {
17778                    Binder.restoreCallingIdentity(origId);
17779                }
17780            }
17781        }
17782
17783        @Override
17784        public ActivityManager.RecentTaskInfo getTaskInfo() {
17785            // Ensure that we are called from the same process that created this AppTask
17786            if (mCallingUid != Binder.getCallingUid()) {
17787                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17788                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17789                return null;
17790            }
17791
17792            synchronized (ActivityManagerService.this) {
17793                long origId = Binder.clearCallingIdentity();
17794                try {
17795                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17796                    if (tr != null) {
17797                        return createRecentTaskInfoFromTaskRecord(tr);
17798                    }
17799                } finally {
17800                    Binder.restoreCallingIdentity(origId);
17801                }
17802                return null;
17803            }
17804        }
17805    }
17806}
17807