ActivityManagerService.java revision 66adae84d7e1475c4422d80860eed17e234ab8a9
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 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3558        if (task == null) {
3559            throw new ActivityNotFoundException("Task " + taskId + " not found.");
3560        }
3561        return startActivityInPackage(task.mCallingUid, task.mCallingPackage,
3562                task.intent, null, null, null, 0, 0, options, task.userId,
3563                null);
3564    }
3565
3566    final int startActivityInPackage(int uid, String callingPackage,
3567            Intent intent, String resolvedType, IBinder resultTo,
3568            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3569                    IActivityContainer container) {
3570
3571        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3572                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3573
3574        // TODO: Switch to user app stacks here.
3575        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3576                null, null, resultTo, resultWho, requestCode, startFlags,
3577                null, null, null, null, options, userId, container);
3578        return ret;
3579    }
3580
3581    @Override
3582    public final int startActivities(IApplicationThread caller, String callingPackage,
3583            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3584            int userId) {
3585        enforceNotIsolatedCaller("startActivities");
3586        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3587                false, ALLOW_FULL_ONLY, "startActivity", null);
3588        // TODO: Switch to user app stacks here.
3589        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3590                resolvedTypes, resultTo, options, userId);
3591        return ret;
3592    }
3593
3594    final int startActivitiesInPackage(int uid, String callingPackage,
3595            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3596            Bundle options, int userId) {
3597
3598        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3599                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3600        // TODO: Switch to user app stacks here.
3601        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3602                resultTo, options, userId);
3603        return ret;
3604    }
3605
3606    final void addRecentTaskLocked(TaskRecord task) {
3607        int N = mRecentTasks.size();
3608        // Quick case: check if the top-most recent task is the same.
3609        if (N > 0 && mRecentTasks.get(0) == task) {
3610            return;
3611        }
3612        // Another quick case: never add voice sessions.
3613        if (task.voiceSession != null) {
3614            return;
3615        }
3616        // Remove any existing entries that are the same kind of task.
3617        final Intent intent = task.intent;
3618        final boolean document = intent != null && intent.isDocument();
3619        final ComponentName comp = intent.getComponent();
3620
3621        int maxRecents = task.maxRecents - 1;
3622        for (int i=0; i<N; i++) {
3623            final TaskRecord tr = mRecentTasks.get(i);
3624            if (task != tr) {
3625                if (task.userId != tr.userId) {
3626                    continue;
3627                }
3628                if (i > MAX_RECENT_BITMAPS) {
3629                    tr.freeLastThumbnail();
3630                }
3631                final Intent trIntent = tr.intent;
3632                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3633                    (intent == null || !intent.filterEquals(trIntent))) {
3634                    continue;
3635                }
3636                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3637                if (document && trIsDocument) {
3638                    // These are the same document activity (not necessarily the same doc).
3639                    if (maxRecents > 0) {
3640                        --maxRecents;
3641                        continue;
3642                    }
3643                    // Hit the maximum number of documents for this task. Fall through
3644                    // and remove this document from recents.
3645                } else if (document || trIsDocument) {
3646                    // Only one of these is a document. Not the droid we're looking for.
3647                    continue;
3648                }
3649            }
3650
3651            // Either task and tr are the same or, their affinities match or their intents match
3652            // and neither of them is a document, or they are documents using the same activity
3653            // and their maxRecents has been reached.
3654            tr.disposeThumbnail();
3655            mRecentTasks.remove(i);
3656            if (task != tr) {
3657                tr.closeRecentsChain();
3658            }
3659            i--;
3660            N--;
3661            if (task.intent == null) {
3662                // If the new recent task we are adding is not fully
3663                // specified, then replace it with the existing recent task.
3664                task = tr;
3665            }
3666            mTaskPersister.notify(tr, false);
3667        }
3668        if (N >= MAX_RECENT_TASKS) {
3669            final TaskRecord tr = mRecentTasks.remove(N - 1);
3670            tr.disposeThumbnail();
3671            tr.closeRecentsChain();
3672        }
3673        mRecentTasks.add(0, task);
3674    }
3675
3676    @Override
3677    public void reportActivityFullyDrawn(IBinder token) {
3678        synchronized (this) {
3679            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3680            if (r == null) {
3681                return;
3682            }
3683            r.reportFullyDrawnLocked();
3684        }
3685    }
3686
3687    @Override
3688    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3689        synchronized (this) {
3690            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3691            if (r == null) {
3692                return;
3693            }
3694            final long origId = Binder.clearCallingIdentity();
3695            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3696            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3697                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3698            if (config != null) {
3699                r.frozenBeforeDestroy = true;
3700                if (!updateConfigurationLocked(config, r, false, false)) {
3701                    mStackSupervisor.resumeTopActivitiesLocked();
3702                }
3703            }
3704            Binder.restoreCallingIdentity(origId);
3705        }
3706    }
3707
3708    @Override
3709    public int getRequestedOrientation(IBinder token) {
3710        synchronized (this) {
3711            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3712            if (r == null) {
3713                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3714            }
3715            return mWindowManager.getAppOrientation(r.appToken);
3716        }
3717    }
3718
3719    /**
3720     * This is the internal entry point for handling Activity.finish().
3721     *
3722     * @param token The Binder token referencing the Activity we want to finish.
3723     * @param resultCode Result code, if any, from this Activity.
3724     * @param resultData Result data (Intent), if any, from this Activity.
3725     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3726     *            the root Activity in the task.
3727     *
3728     * @return Returns true if the activity successfully finished, or false if it is still running.
3729     */
3730    @Override
3731    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3732            boolean finishTask) {
3733        // Refuse possible leaked file descriptors
3734        if (resultData != null && resultData.hasFileDescriptors() == true) {
3735            throw new IllegalArgumentException("File descriptors passed in Intent");
3736        }
3737
3738        synchronized(this) {
3739            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3740            if (r == null) {
3741                return true;
3742            }
3743            // Keep track of the root activity of the task before we finish it
3744            TaskRecord tr = r.task;
3745            ActivityRecord rootR = tr.getRootActivity();
3746            // Do not allow task to finish in Lock Task mode.
3747            if (tr == mStackSupervisor.mLockTaskModeTask) {
3748                if (rootR == r) {
3749                    mStackSupervisor.showLockTaskToast();
3750                    return false;
3751                }
3752            }
3753            if (mController != null) {
3754                // Find the first activity that is not finishing.
3755                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3756                if (next != null) {
3757                    // ask watcher if this is allowed
3758                    boolean resumeOK = true;
3759                    try {
3760                        resumeOK = mController.activityResuming(next.packageName);
3761                    } catch (RemoteException e) {
3762                        mController = null;
3763                        Watchdog.getInstance().setActivityController(null);
3764                    }
3765
3766                    if (!resumeOK) {
3767                        return false;
3768                    }
3769                }
3770            }
3771            final long origId = Binder.clearCallingIdentity();
3772            try {
3773                boolean res;
3774                if (finishTask && r == rootR) {
3775                    // If requested, remove the task that is associated to this activity only if it
3776                    // was the root activity in the task.  The result code and data is ignored because
3777                    // we don't support returning them across task boundaries.
3778                    res = removeTaskByIdLocked(tr.taskId, 0);
3779                } else {
3780                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3781                            resultData, "app-request", true);
3782                }
3783                return res;
3784            } finally {
3785                Binder.restoreCallingIdentity(origId);
3786            }
3787        }
3788    }
3789
3790    @Override
3791    public final void finishHeavyWeightApp() {
3792        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3793                != PackageManager.PERMISSION_GRANTED) {
3794            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3795                    + Binder.getCallingPid()
3796                    + ", uid=" + Binder.getCallingUid()
3797                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3798            Slog.w(TAG, msg);
3799            throw new SecurityException(msg);
3800        }
3801
3802        synchronized(this) {
3803            if (mHeavyWeightProcess == null) {
3804                return;
3805            }
3806
3807            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3808                    mHeavyWeightProcess.activities);
3809            for (int i=0; i<activities.size(); i++) {
3810                ActivityRecord r = activities.get(i);
3811                if (!r.finishing) {
3812                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3813                            null, "finish-heavy", true);
3814                }
3815            }
3816
3817            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3818                    mHeavyWeightProcess.userId, 0));
3819            mHeavyWeightProcess = null;
3820        }
3821    }
3822
3823    @Override
3824    public void crashApplication(int uid, int initialPid, String packageName,
3825            String message) {
3826        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3827                != PackageManager.PERMISSION_GRANTED) {
3828            String msg = "Permission Denial: crashApplication() from pid="
3829                    + Binder.getCallingPid()
3830                    + ", uid=" + Binder.getCallingUid()
3831                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3832            Slog.w(TAG, msg);
3833            throw new SecurityException(msg);
3834        }
3835
3836        synchronized(this) {
3837            ProcessRecord proc = null;
3838
3839            // Figure out which process to kill.  We don't trust that initialPid
3840            // still has any relation to current pids, so must scan through the
3841            // list.
3842            synchronized (mPidsSelfLocked) {
3843                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3844                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3845                    if (p.uid != uid) {
3846                        continue;
3847                    }
3848                    if (p.pid == initialPid) {
3849                        proc = p;
3850                        break;
3851                    }
3852                    if (p.pkgList.containsKey(packageName)) {
3853                        proc = p;
3854                    }
3855                }
3856            }
3857
3858            if (proc == null) {
3859                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3860                        + " initialPid=" + initialPid
3861                        + " packageName=" + packageName);
3862                return;
3863            }
3864
3865            if (proc.thread != null) {
3866                if (proc.pid == Process.myPid()) {
3867                    Log.w(TAG, "crashApplication: trying to crash self!");
3868                    return;
3869                }
3870                long ident = Binder.clearCallingIdentity();
3871                try {
3872                    proc.thread.scheduleCrash(message);
3873                } catch (RemoteException e) {
3874                }
3875                Binder.restoreCallingIdentity(ident);
3876            }
3877        }
3878    }
3879
3880    @Override
3881    public final void finishSubActivity(IBinder token, String resultWho,
3882            int requestCode) {
3883        synchronized(this) {
3884            final long origId = Binder.clearCallingIdentity();
3885            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3886            if (r != null) {
3887                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3888            }
3889            Binder.restoreCallingIdentity(origId);
3890        }
3891    }
3892
3893    @Override
3894    public boolean finishActivityAffinity(IBinder token) {
3895        synchronized(this) {
3896            final long origId = Binder.clearCallingIdentity();
3897            try {
3898                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3899
3900                ActivityRecord rootR = r.task.getRootActivity();
3901                // Do not allow task to finish in Lock Task mode.
3902                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3903                    if (rootR == r) {
3904                        mStackSupervisor.showLockTaskToast();
3905                        return false;
3906                    }
3907                }
3908                boolean res = false;
3909                if (r != null) {
3910                    res = r.task.stack.finishActivityAffinityLocked(r);
3911                }
3912                return res;
3913            } finally {
3914                Binder.restoreCallingIdentity(origId);
3915            }
3916        }
3917    }
3918
3919    @Override
3920    public void finishVoiceTask(IVoiceInteractionSession session) {
3921        synchronized(this) {
3922            final long origId = Binder.clearCallingIdentity();
3923            try {
3924                mStackSupervisor.finishVoiceTask(session);
3925            } finally {
3926                Binder.restoreCallingIdentity(origId);
3927            }
3928        }
3929
3930    }
3931
3932    @Override
3933    public boolean willActivityBeVisible(IBinder token) {
3934        synchronized(this) {
3935            ActivityStack stack = ActivityRecord.getStackLocked(token);
3936            if (stack != null) {
3937                return stack.willActivityBeVisibleLocked(token);
3938            }
3939            return false;
3940        }
3941    }
3942
3943    @Override
3944    public void overridePendingTransition(IBinder token, String packageName,
3945            int enterAnim, int exitAnim) {
3946        synchronized(this) {
3947            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3948            if (self == null) {
3949                return;
3950            }
3951
3952            final long origId = Binder.clearCallingIdentity();
3953
3954            if (self.state == ActivityState.RESUMED
3955                    || self.state == ActivityState.PAUSING) {
3956                mWindowManager.overridePendingAppTransition(packageName,
3957                        enterAnim, exitAnim, null);
3958            }
3959
3960            Binder.restoreCallingIdentity(origId);
3961        }
3962    }
3963
3964    /**
3965     * Main function for removing an existing process from the activity manager
3966     * as a result of that process going away.  Clears out all connections
3967     * to the process.
3968     */
3969    private final void handleAppDiedLocked(ProcessRecord app,
3970            boolean restarting, boolean allowRestart) {
3971        int pid = app.pid;
3972        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3973        if (!restarting) {
3974            removeLruProcessLocked(app);
3975            if (pid > 0) {
3976                ProcessList.remove(pid);
3977            }
3978        }
3979
3980        if (mProfileProc == app) {
3981            clearProfilerLocked();
3982        }
3983
3984        // Remove this application's activities from active lists.
3985        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3986
3987        app.activities.clear();
3988
3989        if (app.instrumentationClass != null) {
3990            Slog.w(TAG, "Crash of app " + app.processName
3991                  + " running instrumentation " + app.instrumentationClass);
3992            Bundle info = new Bundle();
3993            info.putString("shortMsg", "Process crashed.");
3994            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3995        }
3996
3997        if (!restarting) {
3998            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3999                // If there was nothing to resume, and we are not already
4000                // restarting this process, but there is a visible activity that
4001                // is hosted by the process...  then make sure all visible
4002                // activities are running, taking care of restarting this
4003                // process.
4004                if (hasVisibleActivities) {
4005                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4006                }
4007            }
4008        }
4009    }
4010
4011    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4012        IBinder threadBinder = thread.asBinder();
4013        // Find the application record.
4014        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4015            ProcessRecord rec = mLruProcesses.get(i);
4016            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4017                return i;
4018            }
4019        }
4020        return -1;
4021    }
4022
4023    final ProcessRecord getRecordForAppLocked(
4024            IApplicationThread thread) {
4025        if (thread == null) {
4026            return null;
4027        }
4028
4029        int appIndex = getLRURecordIndexForAppLocked(thread);
4030        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4031    }
4032
4033    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4034        // If there are no longer any background processes running,
4035        // and the app that died was not running instrumentation,
4036        // then tell everyone we are now low on memory.
4037        boolean haveBg = false;
4038        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4039            ProcessRecord rec = mLruProcesses.get(i);
4040            if (rec.thread != null
4041                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4042                haveBg = true;
4043                break;
4044            }
4045        }
4046
4047        if (!haveBg) {
4048            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4049            if (doReport) {
4050                long now = SystemClock.uptimeMillis();
4051                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4052                    doReport = false;
4053                } else {
4054                    mLastMemUsageReportTime = now;
4055                }
4056            }
4057            final ArrayList<ProcessMemInfo> memInfos
4058                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4059            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4060            long now = SystemClock.uptimeMillis();
4061            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4062                ProcessRecord rec = mLruProcesses.get(i);
4063                if (rec == dyingProc || rec.thread == null) {
4064                    continue;
4065                }
4066                if (doReport) {
4067                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4068                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4069                }
4070                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4071                    // The low memory report is overriding any current
4072                    // state for a GC request.  Make sure to do
4073                    // heavy/important/visible/foreground processes first.
4074                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4075                        rec.lastRequestedGc = 0;
4076                    } else {
4077                        rec.lastRequestedGc = rec.lastLowMemory;
4078                    }
4079                    rec.reportLowMemory = true;
4080                    rec.lastLowMemory = now;
4081                    mProcessesToGc.remove(rec);
4082                    addProcessToGcListLocked(rec);
4083                }
4084            }
4085            if (doReport) {
4086                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4087                mHandler.sendMessage(msg);
4088            }
4089            scheduleAppGcsLocked();
4090        }
4091    }
4092
4093    final void appDiedLocked(ProcessRecord app, int pid,
4094            IApplicationThread thread) {
4095
4096        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4097        synchronized (stats) {
4098            stats.noteProcessDiedLocked(app.info.uid, pid);
4099        }
4100
4101        Process.killProcessGroup(app.info.uid, pid);
4102
4103        // Clean up already done if the process has been re-started.
4104        if (app.pid == pid && app.thread != null &&
4105                app.thread.asBinder() == thread.asBinder()) {
4106            boolean doLowMem = app.instrumentationClass == null;
4107            boolean doOomAdj = doLowMem;
4108            if (!app.killedByAm) {
4109                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4110                        + ") has died.");
4111                mAllowLowerMemLevel = true;
4112            } else {
4113                // Note that we always want to do oom adj to update our state with the
4114                // new number of procs.
4115                mAllowLowerMemLevel = false;
4116                doLowMem = false;
4117            }
4118            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4119            if (DEBUG_CLEANUP) Slog.v(
4120                TAG, "Dying app: " + app + ", pid: " + pid
4121                + ", thread: " + thread.asBinder());
4122            handleAppDiedLocked(app, false, true);
4123
4124            if (doOomAdj) {
4125                updateOomAdjLocked();
4126            }
4127            if (doLowMem) {
4128                doLowMemReportIfNeededLocked(app);
4129            }
4130        } else if (app.pid != pid) {
4131            // A new process has already been started.
4132            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4133                    + ") has died and restarted (pid " + app.pid + ").");
4134            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4135        } else if (DEBUG_PROCESSES) {
4136            Slog.d(TAG, "Received spurious death notification for thread "
4137                    + thread.asBinder());
4138        }
4139    }
4140
4141    /**
4142     * If a stack trace dump file is configured, dump process stack traces.
4143     * @param clearTraces causes the dump file to be erased prior to the new
4144     *    traces being written, if true; when false, the new traces will be
4145     *    appended to any existing file content.
4146     * @param firstPids of dalvik VM processes to dump stack traces for first
4147     * @param lastPids of dalvik VM processes to dump stack traces for last
4148     * @param nativeProcs optional list of native process names to dump stack crawls
4149     * @return file containing stack traces, or null if no dump file is configured
4150     */
4151    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4152            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4153        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4154        if (tracesPath == null || tracesPath.length() == 0) {
4155            return null;
4156        }
4157
4158        File tracesFile = new File(tracesPath);
4159        try {
4160            File tracesDir = tracesFile.getParentFile();
4161            if (!tracesDir.exists()) {
4162                tracesFile.mkdirs();
4163                if (!SELinux.restorecon(tracesDir)) {
4164                    return null;
4165                }
4166            }
4167            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4168
4169            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4170            tracesFile.createNewFile();
4171            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4172        } catch (IOException e) {
4173            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4174            return null;
4175        }
4176
4177        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4178        return tracesFile;
4179    }
4180
4181    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4182            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4183        // Use a FileObserver to detect when traces finish writing.
4184        // The order of traces is considered important to maintain for legibility.
4185        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4186            @Override
4187            public synchronized void onEvent(int event, String path) { notify(); }
4188        };
4189
4190        try {
4191            observer.startWatching();
4192
4193            // First collect all of the stacks of the most important pids.
4194            if (firstPids != null) {
4195                try {
4196                    int num = firstPids.size();
4197                    for (int i = 0; i < num; i++) {
4198                        synchronized (observer) {
4199                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4200                            observer.wait(200);  // Wait for write-close, give up after 200msec
4201                        }
4202                    }
4203                } catch (InterruptedException e) {
4204                    Log.wtf(TAG, e);
4205                }
4206            }
4207
4208            // Next collect the stacks of the native pids
4209            if (nativeProcs != null) {
4210                int[] pids = Process.getPidsForCommands(nativeProcs);
4211                if (pids != null) {
4212                    for (int pid : pids) {
4213                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4214                    }
4215                }
4216            }
4217
4218            // Lastly, measure CPU usage.
4219            if (processCpuTracker != null) {
4220                processCpuTracker.init();
4221                System.gc();
4222                processCpuTracker.update();
4223                try {
4224                    synchronized (processCpuTracker) {
4225                        processCpuTracker.wait(500); // measure over 1/2 second.
4226                    }
4227                } catch (InterruptedException e) {
4228                }
4229                processCpuTracker.update();
4230
4231                // We'll take the stack crawls of just the top apps using CPU.
4232                final int N = processCpuTracker.countWorkingStats();
4233                int numProcs = 0;
4234                for (int i=0; i<N && numProcs<5; i++) {
4235                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4236                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4237                        numProcs++;
4238                        try {
4239                            synchronized (observer) {
4240                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4241                                observer.wait(200);  // Wait for write-close, give up after 200msec
4242                            }
4243                        } catch (InterruptedException e) {
4244                            Log.wtf(TAG, e);
4245                        }
4246
4247                    }
4248                }
4249            }
4250        } finally {
4251            observer.stopWatching();
4252        }
4253    }
4254
4255    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4256        if (true || IS_USER_BUILD) {
4257            return;
4258        }
4259        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4260        if (tracesPath == null || tracesPath.length() == 0) {
4261            return;
4262        }
4263
4264        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4265        StrictMode.allowThreadDiskWrites();
4266        try {
4267            final File tracesFile = new File(tracesPath);
4268            final File tracesDir = tracesFile.getParentFile();
4269            final File tracesTmp = new File(tracesDir, "__tmp__");
4270            try {
4271                if (!tracesDir.exists()) {
4272                    tracesFile.mkdirs();
4273                    if (!SELinux.restorecon(tracesDir.getPath())) {
4274                        return;
4275                    }
4276                }
4277                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4278
4279                if (tracesFile.exists()) {
4280                    tracesTmp.delete();
4281                    tracesFile.renameTo(tracesTmp);
4282                }
4283                StringBuilder sb = new StringBuilder();
4284                Time tobj = new Time();
4285                tobj.set(System.currentTimeMillis());
4286                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4287                sb.append(": ");
4288                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4289                sb.append(" since ");
4290                sb.append(msg);
4291                FileOutputStream fos = new FileOutputStream(tracesFile);
4292                fos.write(sb.toString().getBytes());
4293                if (app == null) {
4294                    fos.write("\n*** No application process!".getBytes());
4295                }
4296                fos.close();
4297                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4298            } catch (IOException e) {
4299                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4300                return;
4301            }
4302
4303            if (app != null) {
4304                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4305                firstPids.add(app.pid);
4306                dumpStackTraces(tracesPath, firstPids, null, null, null);
4307            }
4308
4309            File lastTracesFile = null;
4310            File curTracesFile = null;
4311            for (int i=9; i>=0; i--) {
4312                String name = String.format(Locale.US, "slow%02d.txt", i);
4313                curTracesFile = new File(tracesDir, name);
4314                if (curTracesFile.exists()) {
4315                    if (lastTracesFile != null) {
4316                        curTracesFile.renameTo(lastTracesFile);
4317                    } else {
4318                        curTracesFile.delete();
4319                    }
4320                }
4321                lastTracesFile = curTracesFile;
4322            }
4323            tracesFile.renameTo(curTracesFile);
4324            if (tracesTmp.exists()) {
4325                tracesTmp.renameTo(tracesFile);
4326            }
4327        } finally {
4328            StrictMode.setThreadPolicy(oldPolicy);
4329        }
4330    }
4331
4332    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4333            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4334        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4335        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4336
4337        if (mController != null) {
4338            try {
4339                // 0 == continue, -1 = kill process immediately
4340                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4341                if (res < 0 && app.pid != MY_PID) {
4342                    Process.killProcess(app.pid);
4343                    Process.killProcessGroup(app.info.uid, app.pid);
4344                }
4345            } catch (RemoteException e) {
4346                mController = null;
4347                Watchdog.getInstance().setActivityController(null);
4348            }
4349        }
4350
4351        long anrTime = SystemClock.uptimeMillis();
4352        if (MONITOR_CPU_USAGE) {
4353            updateCpuStatsNow();
4354        }
4355
4356        synchronized (this) {
4357            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4358            if (mShuttingDown) {
4359                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4360                return;
4361            } else if (app.notResponding) {
4362                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4363                return;
4364            } else if (app.crashing) {
4365                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4366                return;
4367            }
4368
4369            // In case we come through here for the same app before completing
4370            // this one, mark as anring now so we will bail out.
4371            app.notResponding = true;
4372
4373            // Log the ANR to the event log.
4374            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4375                    app.processName, app.info.flags, annotation);
4376
4377            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4378            firstPids.add(app.pid);
4379
4380            int parentPid = app.pid;
4381            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4382            if (parentPid != app.pid) firstPids.add(parentPid);
4383
4384            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4385
4386            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4387                ProcessRecord r = mLruProcesses.get(i);
4388                if (r != null && r.thread != null) {
4389                    int pid = r.pid;
4390                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4391                        if (r.persistent) {
4392                            firstPids.add(pid);
4393                        } else {
4394                            lastPids.put(pid, Boolean.TRUE);
4395                        }
4396                    }
4397                }
4398            }
4399        }
4400
4401        // Log the ANR to the main log.
4402        StringBuilder info = new StringBuilder();
4403        info.setLength(0);
4404        info.append("ANR in ").append(app.processName);
4405        if (activity != null && activity.shortComponentName != null) {
4406            info.append(" (").append(activity.shortComponentName).append(")");
4407        }
4408        info.append("\n");
4409        info.append("PID: ").append(app.pid).append("\n");
4410        if (annotation != null) {
4411            info.append("Reason: ").append(annotation).append("\n");
4412        }
4413        if (parent != null && parent != activity) {
4414            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4415        }
4416
4417        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4418
4419        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4420                NATIVE_STACKS_OF_INTEREST);
4421
4422        String cpuInfo = null;
4423        if (MONITOR_CPU_USAGE) {
4424            updateCpuStatsNow();
4425            synchronized (mProcessCpuThread) {
4426                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4427            }
4428            info.append(processCpuTracker.printCurrentLoad());
4429            info.append(cpuInfo);
4430        }
4431
4432        info.append(processCpuTracker.printCurrentState(anrTime));
4433
4434        Slog.e(TAG, info.toString());
4435        if (tracesFile == null) {
4436            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4437            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4438        }
4439
4440        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4441                cpuInfo, tracesFile, null);
4442
4443        if (mController != null) {
4444            try {
4445                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4446                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4447                if (res != 0) {
4448                    if (res < 0 && app.pid != MY_PID) {
4449                        Process.killProcess(app.pid);
4450                        Process.killProcessGroup(app.info.uid, app.pid);
4451                    } else {
4452                        synchronized (this) {
4453                            mServices.scheduleServiceTimeoutLocked(app);
4454                        }
4455                    }
4456                    return;
4457                }
4458            } catch (RemoteException e) {
4459                mController = null;
4460                Watchdog.getInstance().setActivityController(null);
4461            }
4462        }
4463
4464        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4465        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4466                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4467
4468        synchronized (this) {
4469            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4470                killUnneededProcessLocked(app, "background ANR");
4471                return;
4472            }
4473
4474            // Set the app's notResponding state, and look up the errorReportReceiver
4475            makeAppNotRespondingLocked(app,
4476                    activity != null ? activity.shortComponentName : null,
4477                    annotation != null ? "ANR " + annotation : "ANR",
4478                    info.toString());
4479
4480            // Bring up the infamous App Not Responding dialog
4481            Message msg = Message.obtain();
4482            HashMap<String, Object> map = new HashMap<String, Object>();
4483            msg.what = SHOW_NOT_RESPONDING_MSG;
4484            msg.obj = map;
4485            msg.arg1 = aboveSystem ? 1 : 0;
4486            map.put("app", app);
4487            if (activity != null) {
4488                map.put("activity", activity);
4489            }
4490
4491            mHandler.sendMessage(msg);
4492        }
4493    }
4494
4495    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4496        if (!mLaunchWarningShown) {
4497            mLaunchWarningShown = true;
4498            mHandler.post(new Runnable() {
4499                @Override
4500                public void run() {
4501                    synchronized (ActivityManagerService.this) {
4502                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4503                        d.show();
4504                        mHandler.postDelayed(new Runnable() {
4505                            @Override
4506                            public void run() {
4507                                synchronized (ActivityManagerService.this) {
4508                                    d.dismiss();
4509                                    mLaunchWarningShown = false;
4510                                }
4511                            }
4512                        }, 4000);
4513                    }
4514                }
4515            });
4516        }
4517    }
4518
4519    @Override
4520    public boolean clearApplicationUserData(final String packageName,
4521            final IPackageDataObserver observer, int userId) {
4522        enforceNotIsolatedCaller("clearApplicationUserData");
4523        int uid = Binder.getCallingUid();
4524        int pid = Binder.getCallingPid();
4525        userId = handleIncomingUser(pid, uid,
4526                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4527        long callingId = Binder.clearCallingIdentity();
4528        try {
4529            IPackageManager pm = AppGlobals.getPackageManager();
4530            int pkgUid = -1;
4531            synchronized(this) {
4532                try {
4533                    pkgUid = pm.getPackageUid(packageName, userId);
4534                } catch (RemoteException e) {
4535                }
4536                if (pkgUid == -1) {
4537                    Slog.w(TAG, "Invalid packageName: " + packageName);
4538                    if (observer != null) {
4539                        try {
4540                            observer.onRemoveCompleted(packageName, false);
4541                        } catch (RemoteException e) {
4542                            Slog.i(TAG, "Observer no longer exists.");
4543                        }
4544                    }
4545                    return false;
4546                }
4547                if (uid == pkgUid || checkComponentPermission(
4548                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4549                        pid, uid, -1, true)
4550                        == PackageManager.PERMISSION_GRANTED) {
4551                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4552                } else {
4553                    throw new SecurityException("PID " + pid + " does not have permission "
4554                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4555                                    + " of package " + packageName);
4556                }
4557            }
4558
4559            try {
4560                // Clear application user data
4561                pm.clearApplicationUserData(packageName, observer, userId);
4562
4563                // Remove all permissions granted from/to this package
4564                removeUriPermissionsForPackageLocked(packageName, userId, true);
4565
4566                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4567                        Uri.fromParts("package", packageName, null));
4568                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4569                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4570                        null, null, 0, null, null, null, false, false, userId);
4571            } catch (RemoteException e) {
4572            }
4573        } finally {
4574            Binder.restoreCallingIdentity(callingId);
4575        }
4576        return true;
4577    }
4578
4579    @Override
4580    public void killBackgroundProcesses(final String packageName, int userId) {
4581        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4582                != PackageManager.PERMISSION_GRANTED &&
4583                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4584                        != PackageManager.PERMISSION_GRANTED) {
4585            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4586                    + Binder.getCallingPid()
4587                    + ", uid=" + Binder.getCallingUid()
4588                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4589            Slog.w(TAG, msg);
4590            throw new SecurityException(msg);
4591        }
4592
4593        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4594                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4595        long callingId = Binder.clearCallingIdentity();
4596        try {
4597            IPackageManager pm = AppGlobals.getPackageManager();
4598            synchronized(this) {
4599                int appId = -1;
4600                try {
4601                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4602                } catch (RemoteException e) {
4603                }
4604                if (appId == -1) {
4605                    Slog.w(TAG, "Invalid packageName: " + packageName);
4606                    return;
4607                }
4608                killPackageProcessesLocked(packageName, appId, userId,
4609                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4610            }
4611        } finally {
4612            Binder.restoreCallingIdentity(callingId);
4613        }
4614    }
4615
4616    @Override
4617    public void killAllBackgroundProcesses() {
4618        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4619                != PackageManager.PERMISSION_GRANTED) {
4620            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4621                    + Binder.getCallingPid()
4622                    + ", uid=" + Binder.getCallingUid()
4623                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4624            Slog.w(TAG, msg);
4625            throw new SecurityException(msg);
4626        }
4627
4628        long callingId = Binder.clearCallingIdentity();
4629        try {
4630            synchronized(this) {
4631                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4632                final int NP = mProcessNames.getMap().size();
4633                for (int ip=0; ip<NP; ip++) {
4634                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4635                    final int NA = apps.size();
4636                    for (int ia=0; ia<NA; ia++) {
4637                        ProcessRecord app = apps.valueAt(ia);
4638                        if (app.persistent) {
4639                            // we don't kill persistent processes
4640                            continue;
4641                        }
4642                        if (app.removed) {
4643                            procs.add(app);
4644                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4645                            app.removed = true;
4646                            procs.add(app);
4647                        }
4648                    }
4649                }
4650
4651                int N = procs.size();
4652                for (int i=0; i<N; i++) {
4653                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4654                }
4655                mAllowLowerMemLevel = true;
4656                updateOomAdjLocked();
4657                doLowMemReportIfNeededLocked(null);
4658            }
4659        } finally {
4660            Binder.restoreCallingIdentity(callingId);
4661        }
4662    }
4663
4664    @Override
4665    public void forceStopPackage(final String packageName, int userId) {
4666        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4667                != PackageManager.PERMISSION_GRANTED) {
4668            String msg = "Permission Denial: forceStopPackage() from pid="
4669                    + Binder.getCallingPid()
4670                    + ", uid=" + Binder.getCallingUid()
4671                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4672            Slog.w(TAG, msg);
4673            throw new SecurityException(msg);
4674        }
4675        final int callingPid = Binder.getCallingPid();
4676        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4677                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4678        long callingId = Binder.clearCallingIdentity();
4679        try {
4680            IPackageManager pm = AppGlobals.getPackageManager();
4681            synchronized(this) {
4682                int[] users = userId == UserHandle.USER_ALL
4683                        ? getUsersLocked() : new int[] { userId };
4684                for (int user : users) {
4685                    int pkgUid = -1;
4686                    try {
4687                        pkgUid = pm.getPackageUid(packageName, user);
4688                    } catch (RemoteException e) {
4689                    }
4690                    if (pkgUid == -1) {
4691                        Slog.w(TAG, "Invalid packageName: " + packageName);
4692                        continue;
4693                    }
4694                    try {
4695                        pm.setPackageStoppedState(packageName, true, user);
4696                    } catch (RemoteException e) {
4697                    } catch (IllegalArgumentException e) {
4698                        Slog.w(TAG, "Failed trying to unstop package "
4699                                + packageName + ": " + e);
4700                    }
4701                    if (isUserRunningLocked(user, false)) {
4702                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4703                    }
4704                }
4705            }
4706        } finally {
4707            Binder.restoreCallingIdentity(callingId);
4708        }
4709    }
4710
4711    @Override
4712    public void addPackageDependency(String packageName) {
4713        synchronized (this) {
4714            int callingPid = Binder.getCallingPid();
4715            if (callingPid == Process.myPid()) {
4716                //  Yeah, um, no.
4717                Slog.w(TAG, "Can't addPackageDependency on system process");
4718                return;
4719            }
4720            ProcessRecord proc;
4721            synchronized (mPidsSelfLocked) {
4722                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4723            }
4724            if (proc != null) {
4725                if (proc.pkgDeps == null) {
4726                    proc.pkgDeps = new ArraySet<String>(1);
4727                }
4728                proc.pkgDeps.add(packageName);
4729            }
4730        }
4731    }
4732
4733    /*
4734     * The pkg name and app id have to be specified.
4735     */
4736    @Override
4737    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4738        if (pkg == null) {
4739            return;
4740        }
4741        // Make sure the uid is valid.
4742        if (appid < 0) {
4743            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4744            return;
4745        }
4746        int callerUid = Binder.getCallingUid();
4747        // Only the system server can kill an application
4748        if (callerUid == Process.SYSTEM_UID) {
4749            // Post an aysnc message to kill the application
4750            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4751            msg.arg1 = appid;
4752            msg.arg2 = 0;
4753            Bundle bundle = new Bundle();
4754            bundle.putString("pkg", pkg);
4755            bundle.putString("reason", reason);
4756            msg.obj = bundle;
4757            mHandler.sendMessage(msg);
4758        } else {
4759            throw new SecurityException(callerUid + " cannot kill pkg: " +
4760                    pkg);
4761        }
4762    }
4763
4764    @Override
4765    public void closeSystemDialogs(String reason) {
4766        enforceNotIsolatedCaller("closeSystemDialogs");
4767
4768        final int pid = Binder.getCallingPid();
4769        final int uid = Binder.getCallingUid();
4770        final long origId = Binder.clearCallingIdentity();
4771        try {
4772            synchronized (this) {
4773                // Only allow this from foreground processes, so that background
4774                // applications can't abuse it to prevent system UI from being shown.
4775                if (uid >= Process.FIRST_APPLICATION_UID) {
4776                    ProcessRecord proc;
4777                    synchronized (mPidsSelfLocked) {
4778                        proc = mPidsSelfLocked.get(pid);
4779                    }
4780                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4781                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4782                                + " from background process " + proc);
4783                        return;
4784                    }
4785                }
4786                closeSystemDialogsLocked(reason);
4787            }
4788        } finally {
4789            Binder.restoreCallingIdentity(origId);
4790        }
4791    }
4792
4793    void closeSystemDialogsLocked(String reason) {
4794        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4795        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4796                | Intent.FLAG_RECEIVER_FOREGROUND);
4797        if (reason != null) {
4798            intent.putExtra("reason", reason);
4799        }
4800        mWindowManager.closeSystemDialogs(reason);
4801
4802        mStackSupervisor.closeSystemDialogsLocked();
4803
4804        broadcastIntentLocked(null, null, intent, null,
4805                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4806                Process.SYSTEM_UID, UserHandle.USER_ALL);
4807    }
4808
4809    @Override
4810    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4811        enforceNotIsolatedCaller("getProcessMemoryInfo");
4812        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4813        for (int i=pids.length-1; i>=0; i--) {
4814            ProcessRecord proc;
4815            int oomAdj;
4816            synchronized (this) {
4817                synchronized (mPidsSelfLocked) {
4818                    proc = mPidsSelfLocked.get(pids[i]);
4819                    oomAdj = proc != null ? proc.setAdj : 0;
4820                }
4821            }
4822            infos[i] = new Debug.MemoryInfo();
4823            Debug.getMemoryInfo(pids[i], infos[i]);
4824            if (proc != null) {
4825                synchronized (this) {
4826                    if (proc.thread != null && proc.setAdj == oomAdj) {
4827                        // Record this for posterity if the process has been stable.
4828                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4829                                infos[i].getTotalUss(), false, proc.pkgList);
4830                    }
4831                }
4832            }
4833        }
4834        return infos;
4835    }
4836
4837    @Override
4838    public long[] getProcessPss(int[] pids) {
4839        enforceNotIsolatedCaller("getProcessPss");
4840        long[] pss = new long[pids.length];
4841        for (int i=pids.length-1; i>=0; i--) {
4842            ProcessRecord proc;
4843            int oomAdj;
4844            synchronized (this) {
4845                synchronized (mPidsSelfLocked) {
4846                    proc = mPidsSelfLocked.get(pids[i]);
4847                    oomAdj = proc != null ? proc.setAdj : 0;
4848                }
4849            }
4850            long[] tmpUss = new long[1];
4851            pss[i] = Debug.getPss(pids[i], tmpUss);
4852            if (proc != null) {
4853                synchronized (this) {
4854                    if (proc.thread != null && proc.setAdj == oomAdj) {
4855                        // Record this for posterity if the process has been stable.
4856                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4857                    }
4858                }
4859            }
4860        }
4861        return pss;
4862    }
4863
4864    @Override
4865    public void killApplicationProcess(String processName, int uid) {
4866        if (processName == null) {
4867            return;
4868        }
4869
4870        int callerUid = Binder.getCallingUid();
4871        // Only the system server can kill an application
4872        if (callerUid == Process.SYSTEM_UID) {
4873            synchronized (this) {
4874                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4875                if (app != null && app.thread != null) {
4876                    try {
4877                        app.thread.scheduleSuicide();
4878                    } catch (RemoteException e) {
4879                        // If the other end already died, then our work here is done.
4880                    }
4881                } else {
4882                    Slog.w(TAG, "Process/uid not found attempting kill of "
4883                            + processName + " / " + uid);
4884                }
4885            }
4886        } else {
4887            throw new SecurityException(callerUid + " cannot kill app process: " +
4888                    processName);
4889        }
4890    }
4891
4892    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4893        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4894                false, true, false, false, UserHandle.getUserId(uid), reason);
4895        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4896                Uri.fromParts("package", packageName, null));
4897        if (!mProcessesReady) {
4898            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4899                    | Intent.FLAG_RECEIVER_FOREGROUND);
4900        }
4901        intent.putExtra(Intent.EXTRA_UID, uid);
4902        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4903        broadcastIntentLocked(null, null, intent,
4904                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4905                false, false,
4906                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4907    }
4908
4909    private void forceStopUserLocked(int userId, String reason) {
4910        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4911        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4912        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4913                | Intent.FLAG_RECEIVER_FOREGROUND);
4914        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4915        broadcastIntentLocked(null, null, intent,
4916                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4917                false, false,
4918                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4919    }
4920
4921    private final boolean killPackageProcessesLocked(String packageName, int appId,
4922            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4923            boolean doit, boolean evenPersistent, String reason) {
4924        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4925
4926        // Remove all processes this package may have touched: all with the
4927        // same UID (except for the system or root user), and all whose name
4928        // matches the package name.
4929        final int NP = mProcessNames.getMap().size();
4930        for (int ip=0; ip<NP; ip++) {
4931            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4932            final int NA = apps.size();
4933            for (int ia=0; ia<NA; ia++) {
4934                ProcessRecord app = apps.valueAt(ia);
4935                if (app.persistent && !evenPersistent) {
4936                    // we don't kill persistent processes
4937                    continue;
4938                }
4939                if (app.removed) {
4940                    if (doit) {
4941                        procs.add(app);
4942                    }
4943                    continue;
4944                }
4945
4946                // Skip process if it doesn't meet our oom adj requirement.
4947                if (app.setAdj < minOomAdj) {
4948                    continue;
4949                }
4950
4951                // If no package is specified, we call all processes under the
4952                // give user id.
4953                if (packageName == null) {
4954                    if (app.userId != userId) {
4955                        continue;
4956                    }
4957                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4958                        continue;
4959                    }
4960                // Package has been specified, we want to hit all processes
4961                // that match it.  We need to qualify this by the processes
4962                // that are running under the specified app and user ID.
4963                } else {
4964                    final boolean isDep = app.pkgDeps != null
4965                            && app.pkgDeps.contains(packageName);
4966                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
4967                        continue;
4968                    }
4969                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4970                        continue;
4971                    }
4972                    if (!app.pkgList.containsKey(packageName) && !isDep) {
4973                        continue;
4974                    }
4975                }
4976
4977                // Process has passed all conditions, kill it!
4978                if (!doit) {
4979                    return true;
4980                }
4981                app.removed = true;
4982                procs.add(app);
4983            }
4984        }
4985
4986        int N = procs.size();
4987        for (int i=0; i<N; i++) {
4988            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4989        }
4990        updateOomAdjLocked();
4991        return N > 0;
4992    }
4993
4994    private final boolean forceStopPackageLocked(String name, int appId,
4995            boolean callerWillRestart, boolean purgeCache, boolean doit,
4996            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4997        int i;
4998        int N;
4999
5000        if (userId == UserHandle.USER_ALL && name == null) {
5001            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5002        }
5003
5004        if (appId < 0 && name != null) {
5005            try {
5006                appId = UserHandle.getAppId(
5007                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5008            } catch (RemoteException e) {
5009            }
5010        }
5011
5012        if (doit) {
5013            if (name != null) {
5014                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5015                        + " user=" + userId + ": " + reason);
5016            } else {
5017                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5018            }
5019
5020            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5021            for (int ip=pmap.size()-1; ip>=0; ip--) {
5022                SparseArray<Long> ba = pmap.valueAt(ip);
5023                for (i=ba.size()-1; i>=0; i--) {
5024                    boolean remove = false;
5025                    final int entUid = ba.keyAt(i);
5026                    if (name != null) {
5027                        if (userId == UserHandle.USER_ALL) {
5028                            if (UserHandle.getAppId(entUid) == appId) {
5029                                remove = true;
5030                            }
5031                        } else {
5032                            if (entUid == UserHandle.getUid(userId, appId)) {
5033                                remove = true;
5034                            }
5035                        }
5036                    } else if (UserHandle.getUserId(entUid) == userId) {
5037                        remove = true;
5038                    }
5039                    if (remove) {
5040                        ba.removeAt(i);
5041                    }
5042                }
5043                if (ba.size() == 0) {
5044                    pmap.removeAt(ip);
5045                }
5046            }
5047        }
5048
5049        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5050                -100, callerWillRestart, true, doit, evenPersistent,
5051                name == null ? ("stop user " + userId) : ("stop " + name));
5052
5053        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5054            if (!doit) {
5055                return true;
5056            }
5057            didSomething = true;
5058        }
5059
5060        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5061            if (!doit) {
5062                return true;
5063            }
5064            didSomething = true;
5065        }
5066
5067        if (name == null) {
5068            // Remove all sticky broadcasts from this user.
5069            mStickyBroadcasts.remove(userId);
5070        }
5071
5072        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5073        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5074                userId, providers)) {
5075            if (!doit) {
5076                return true;
5077            }
5078            didSomething = true;
5079        }
5080        N = providers.size();
5081        for (i=0; i<N; i++) {
5082            removeDyingProviderLocked(null, providers.get(i), true);
5083        }
5084
5085        // Remove transient permissions granted from/to this package/user
5086        removeUriPermissionsForPackageLocked(name, userId, false);
5087
5088        if (name == null || uninstalling) {
5089            // Remove pending intents.  For now we only do this when force
5090            // stopping users, because we have some problems when doing this
5091            // for packages -- app widgets are not currently cleaned up for
5092            // such packages, so they can be left with bad pending intents.
5093            if (mIntentSenderRecords.size() > 0) {
5094                Iterator<WeakReference<PendingIntentRecord>> it
5095                        = mIntentSenderRecords.values().iterator();
5096                while (it.hasNext()) {
5097                    WeakReference<PendingIntentRecord> wpir = it.next();
5098                    if (wpir == null) {
5099                        it.remove();
5100                        continue;
5101                    }
5102                    PendingIntentRecord pir = wpir.get();
5103                    if (pir == null) {
5104                        it.remove();
5105                        continue;
5106                    }
5107                    if (name == null) {
5108                        // Stopping user, remove all objects for the user.
5109                        if (pir.key.userId != userId) {
5110                            // Not the same user, skip it.
5111                            continue;
5112                        }
5113                    } else {
5114                        if (UserHandle.getAppId(pir.uid) != appId) {
5115                            // Different app id, skip it.
5116                            continue;
5117                        }
5118                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5119                            // Different user, skip it.
5120                            continue;
5121                        }
5122                        if (!pir.key.packageName.equals(name)) {
5123                            // Different package, skip it.
5124                            continue;
5125                        }
5126                    }
5127                    if (!doit) {
5128                        return true;
5129                    }
5130                    didSomething = true;
5131                    it.remove();
5132                    pir.canceled = true;
5133                    if (pir.key.activity != null) {
5134                        pir.key.activity.pendingResults.remove(pir.ref);
5135                    }
5136                }
5137            }
5138        }
5139
5140        if (doit) {
5141            if (purgeCache && name != null) {
5142                AttributeCache ac = AttributeCache.instance();
5143                if (ac != null) {
5144                    ac.removePackage(name);
5145                }
5146            }
5147            if (mBooted) {
5148                mStackSupervisor.resumeTopActivitiesLocked();
5149                mStackSupervisor.scheduleIdleLocked();
5150            }
5151        }
5152
5153        return didSomething;
5154    }
5155
5156    private final boolean removeProcessLocked(ProcessRecord app,
5157            boolean callerWillRestart, boolean allowRestart, String reason) {
5158        final String name = app.processName;
5159        final int uid = app.uid;
5160        if (DEBUG_PROCESSES) Slog.d(
5161            TAG, "Force removing proc " + app.toShortString() + " (" + name
5162            + "/" + uid + ")");
5163
5164        mProcessNames.remove(name, uid);
5165        mIsolatedProcesses.remove(app.uid);
5166        if (mHeavyWeightProcess == app) {
5167            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5168                    mHeavyWeightProcess.userId, 0));
5169            mHeavyWeightProcess = null;
5170        }
5171        boolean needRestart = false;
5172        if (app.pid > 0 && app.pid != MY_PID) {
5173            int pid = app.pid;
5174            synchronized (mPidsSelfLocked) {
5175                mPidsSelfLocked.remove(pid);
5176                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5177            }
5178            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5179            if (app.isolated) {
5180                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5181            }
5182            killUnneededProcessLocked(app, reason);
5183            Process.killProcessGroup(app.info.uid, app.pid);
5184            handleAppDiedLocked(app, true, allowRestart);
5185            removeLruProcessLocked(app);
5186
5187            if (app.persistent && !app.isolated) {
5188                if (!callerWillRestart) {
5189                    addAppLocked(app.info, false, null /* ABI override */);
5190                } else {
5191                    needRestart = true;
5192                }
5193            }
5194        } else {
5195            mRemovedProcesses.add(app);
5196        }
5197
5198        return needRestart;
5199    }
5200
5201    private final void processStartTimedOutLocked(ProcessRecord app) {
5202        final int pid = app.pid;
5203        boolean gone = false;
5204        synchronized (mPidsSelfLocked) {
5205            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5206            if (knownApp != null && knownApp.thread == null) {
5207                mPidsSelfLocked.remove(pid);
5208                gone = true;
5209            }
5210        }
5211
5212        if (gone) {
5213            Slog.w(TAG, "Process " + app + " failed to attach");
5214            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5215                    pid, app.uid, app.processName);
5216            mProcessNames.remove(app.processName, app.uid);
5217            mIsolatedProcesses.remove(app.uid);
5218            if (mHeavyWeightProcess == app) {
5219                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5220                        mHeavyWeightProcess.userId, 0));
5221                mHeavyWeightProcess = null;
5222            }
5223            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5224            if (app.isolated) {
5225                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5226            }
5227            // Take care of any launching providers waiting for this process.
5228            checkAppInLaunchingProvidersLocked(app, true);
5229            // Take care of any services that are waiting for the process.
5230            mServices.processStartTimedOutLocked(app);
5231            killUnneededProcessLocked(app, "start timeout");
5232            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5233                Slog.w(TAG, "Unattached app died before backup, skipping");
5234                try {
5235                    IBackupManager bm = IBackupManager.Stub.asInterface(
5236                            ServiceManager.getService(Context.BACKUP_SERVICE));
5237                    bm.agentDisconnected(app.info.packageName);
5238                } catch (RemoteException e) {
5239                    // Can't happen; the backup manager is local
5240                }
5241            }
5242            if (isPendingBroadcastProcessLocked(pid)) {
5243                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5244                skipPendingBroadcastLocked(pid);
5245            }
5246        } else {
5247            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5248        }
5249    }
5250
5251    private final boolean attachApplicationLocked(IApplicationThread thread,
5252            int pid) {
5253
5254        // Find the application record that is being attached...  either via
5255        // the pid if we are running in multiple processes, or just pull the
5256        // next app record if we are emulating process with anonymous threads.
5257        ProcessRecord app;
5258        if (pid != MY_PID && pid >= 0) {
5259            synchronized (mPidsSelfLocked) {
5260                app = mPidsSelfLocked.get(pid);
5261            }
5262        } else {
5263            app = null;
5264        }
5265
5266        if (app == null) {
5267            Slog.w(TAG, "No pending application record for pid " + pid
5268                    + " (IApplicationThread " + thread + "); dropping process");
5269            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5270            if (pid > 0 && pid != MY_PID) {
5271                Process.killProcessQuiet(pid);
5272                //TODO: Process.killProcessGroup(app.info.uid, pid);
5273            } else {
5274                try {
5275                    thread.scheduleExit();
5276                } catch (Exception e) {
5277                    // Ignore exceptions.
5278                }
5279            }
5280            return false;
5281        }
5282
5283        // If this application record is still attached to a previous
5284        // process, clean it up now.
5285        if (app.thread != null) {
5286            handleAppDiedLocked(app, true, true);
5287        }
5288
5289        // Tell the process all about itself.
5290
5291        if (localLOGV) Slog.v(
5292                TAG, "Binding process pid " + pid + " to record " + app);
5293
5294        final String processName = app.processName;
5295        try {
5296            AppDeathRecipient adr = new AppDeathRecipient(
5297                    app, pid, thread);
5298            thread.asBinder().linkToDeath(adr, 0);
5299            app.deathRecipient = adr;
5300        } catch (RemoteException e) {
5301            app.resetPackageList(mProcessStats);
5302            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5303            return false;
5304        }
5305
5306        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5307
5308        app.makeActive(thread, mProcessStats);
5309        app.curAdj = app.setAdj = -100;
5310        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5311        app.forcingToForeground = null;
5312        updateProcessForegroundLocked(app, false, false);
5313        app.hasShownUi = false;
5314        app.debugging = false;
5315        app.cached = false;
5316
5317        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5318
5319        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5320        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5321
5322        if (!normalMode) {
5323            Slog.i(TAG, "Launching preboot mode app: " + app);
5324        }
5325
5326        if (localLOGV) Slog.v(
5327            TAG, "New app record " + app
5328            + " thread=" + thread.asBinder() + " pid=" + pid);
5329        try {
5330            int testMode = IApplicationThread.DEBUG_OFF;
5331            if (mDebugApp != null && mDebugApp.equals(processName)) {
5332                testMode = mWaitForDebugger
5333                    ? IApplicationThread.DEBUG_WAIT
5334                    : IApplicationThread.DEBUG_ON;
5335                app.debugging = true;
5336                if (mDebugTransient) {
5337                    mDebugApp = mOrigDebugApp;
5338                    mWaitForDebugger = mOrigWaitForDebugger;
5339                }
5340            }
5341            String profileFile = app.instrumentationProfileFile;
5342            ParcelFileDescriptor profileFd = null;
5343            boolean profileAutoStop = false;
5344            if (mProfileApp != null && mProfileApp.equals(processName)) {
5345                mProfileProc = app;
5346                profileFile = mProfileFile;
5347                profileFd = mProfileFd;
5348                profileAutoStop = mAutoStopProfiler;
5349            }
5350            boolean enableOpenGlTrace = false;
5351            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5352                enableOpenGlTrace = true;
5353                mOpenGlTraceApp = null;
5354            }
5355
5356            // If the app is being launched for restore or full backup, set it up specially
5357            boolean isRestrictedBackupMode = false;
5358            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5359                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5360                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5361                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5362            }
5363
5364            ensurePackageDexOpt(app.instrumentationInfo != null
5365                    ? app.instrumentationInfo.packageName
5366                    : app.info.packageName);
5367            if (app.instrumentationClass != null) {
5368                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5369            }
5370            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5371                    + processName + " with config " + mConfiguration);
5372            ApplicationInfo appInfo = app.instrumentationInfo != null
5373                    ? app.instrumentationInfo : app.info;
5374            app.compat = compatibilityInfoForPackageLocked(appInfo);
5375            if (profileFd != null) {
5376                profileFd = profileFd.dup();
5377            }
5378            thread.bindApplication(processName, appInfo, providers,
5379                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5380                    app.instrumentationArguments, app.instrumentationWatcher,
5381                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5382                    isRestrictedBackupMode || !normalMode, app.persistent,
5383                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5384                    mCoreSettingsObserver.getCoreSettingsLocked());
5385            updateLruProcessLocked(app, false, null);
5386            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5387        } catch (Exception e) {
5388            // todo: Yikes!  What should we do?  For now we will try to
5389            // start another process, but that could easily get us in
5390            // an infinite loop of restarting processes...
5391            Slog.w(TAG, "Exception thrown during bind!", e);
5392
5393            app.resetPackageList(mProcessStats);
5394            app.unlinkDeathRecipient();
5395            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5396            return false;
5397        }
5398
5399        // Remove this record from the list of starting applications.
5400        mPersistentStartingProcesses.remove(app);
5401        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5402                "Attach application locked removing on hold: " + app);
5403        mProcessesOnHold.remove(app);
5404
5405        boolean badApp = false;
5406        boolean didSomething = false;
5407
5408        // See if the top visible activity is waiting to run in this process...
5409        if (normalMode) {
5410            try {
5411                if (mStackSupervisor.attachApplicationLocked(app)) {
5412                    didSomething = true;
5413                }
5414            } catch (Exception e) {
5415                badApp = true;
5416            }
5417        }
5418
5419        // Find any services that should be running in this process...
5420        if (!badApp) {
5421            try {
5422                didSomething |= mServices.attachApplicationLocked(app, processName);
5423            } catch (Exception e) {
5424                badApp = true;
5425            }
5426        }
5427
5428        // Check if a next-broadcast receiver is in this process...
5429        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5430            try {
5431                didSomething |= sendPendingBroadcastsLocked(app);
5432            } catch (Exception e) {
5433                // If the app died trying to launch the receiver we declare it 'bad'
5434                badApp = true;
5435            }
5436        }
5437
5438        // Check whether the next backup agent is in this process...
5439        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5440            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5441            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5442            try {
5443                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5444                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5445                        mBackupTarget.backupMode);
5446            } catch (Exception e) {
5447                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5448                e.printStackTrace();
5449            }
5450        }
5451
5452        if (badApp) {
5453            // todo: Also need to kill application to deal with all
5454            // kinds of exceptions.
5455            handleAppDiedLocked(app, false, true);
5456            return false;
5457        }
5458
5459        if (!didSomething) {
5460            updateOomAdjLocked();
5461        }
5462
5463        return true;
5464    }
5465
5466    @Override
5467    public final void attachApplication(IApplicationThread thread) {
5468        synchronized (this) {
5469            int callingPid = Binder.getCallingPid();
5470            final long origId = Binder.clearCallingIdentity();
5471            attachApplicationLocked(thread, callingPid);
5472            Binder.restoreCallingIdentity(origId);
5473        }
5474    }
5475
5476    @Override
5477    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5478        final long origId = Binder.clearCallingIdentity();
5479        synchronized (this) {
5480            ActivityStack stack = ActivityRecord.getStackLocked(token);
5481            if (stack != null) {
5482                ActivityRecord r =
5483                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5484                if (stopProfiling) {
5485                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5486                        try {
5487                            mProfileFd.close();
5488                        } catch (IOException e) {
5489                        }
5490                        clearProfilerLocked();
5491                    }
5492                }
5493            }
5494        }
5495        Binder.restoreCallingIdentity(origId);
5496    }
5497
5498    void enableScreenAfterBoot() {
5499        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5500                SystemClock.uptimeMillis());
5501        mWindowManager.enableScreenAfterBoot();
5502
5503        synchronized (this) {
5504            updateEventDispatchingLocked();
5505        }
5506    }
5507
5508    @Override
5509    public void showBootMessage(final CharSequence msg, final boolean always) {
5510        enforceNotIsolatedCaller("showBootMessage");
5511        mWindowManager.showBootMessage(msg, always);
5512    }
5513
5514    @Override
5515    public void dismissKeyguardOnNextActivity() {
5516        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5517        final long token = Binder.clearCallingIdentity();
5518        try {
5519            synchronized (this) {
5520                if (DEBUG_LOCKSCREEN) logLockScreen("");
5521                if (mLockScreenShown) {
5522                    mLockScreenShown = false;
5523                    comeOutOfSleepIfNeededLocked();
5524                }
5525                mStackSupervisor.setDismissKeyguard(true);
5526            }
5527        } finally {
5528            Binder.restoreCallingIdentity(token);
5529        }
5530    }
5531
5532    final void finishBooting() {
5533        // Register receivers to handle package update events
5534        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5535
5536        synchronized (this) {
5537            // Ensure that any processes we had put on hold are now started
5538            // up.
5539            final int NP = mProcessesOnHold.size();
5540            if (NP > 0) {
5541                ArrayList<ProcessRecord> procs =
5542                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5543                for (int ip=0; ip<NP; ip++) {
5544                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5545                            + procs.get(ip));
5546                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5547                }
5548            }
5549
5550            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5551                // Start looking for apps that are abusing wake locks.
5552                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5553                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5554                // Tell anyone interested that we are done booting!
5555                SystemProperties.set("sys.boot_completed", "1");
5556                SystemProperties.set("dev.bootcomplete", "1");
5557                for (int i=0; i<mStartedUsers.size(); i++) {
5558                    UserStartedState uss = mStartedUsers.valueAt(i);
5559                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5560                        uss.mState = UserStartedState.STATE_RUNNING;
5561                        final int userId = mStartedUsers.keyAt(i);
5562                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5563                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5564                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5565                        broadcastIntentLocked(null, null, intent, null,
5566                                new IIntentReceiver.Stub() {
5567                                    @Override
5568                                    public void performReceive(Intent intent, int resultCode,
5569                                            String data, Bundle extras, boolean ordered,
5570                                            boolean sticky, int sendingUser) {
5571                                        synchronized (ActivityManagerService.this) {
5572                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5573                                                    true, false);
5574                                        }
5575                                    }
5576                                },
5577                                0, null, null,
5578                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5579                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5580                                userId);
5581                    }
5582                }
5583                scheduleStartProfilesLocked();
5584            }
5585        }
5586    }
5587
5588    final void ensureBootCompleted() {
5589        boolean booting;
5590        boolean enableScreen;
5591        synchronized (this) {
5592            booting = mBooting;
5593            mBooting = false;
5594            enableScreen = !mBooted;
5595            mBooted = true;
5596        }
5597
5598        if (booting) {
5599            finishBooting();
5600        }
5601
5602        if (enableScreen) {
5603            enableScreenAfterBoot();
5604        }
5605    }
5606
5607    @Override
5608    public final void activityResumed(IBinder token) {
5609        final long origId = Binder.clearCallingIdentity();
5610        synchronized(this) {
5611            ActivityStack stack = ActivityRecord.getStackLocked(token);
5612            if (stack != null) {
5613                ActivityRecord.activityResumedLocked(token);
5614            }
5615        }
5616        Binder.restoreCallingIdentity(origId);
5617    }
5618
5619    @Override
5620    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5621        final long origId = Binder.clearCallingIdentity();
5622        synchronized(this) {
5623            ActivityStack stack = ActivityRecord.getStackLocked(token);
5624            if (stack != null) {
5625                stack.activityPausedLocked(token, false, persistentState);
5626            }
5627        }
5628        Binder.restoreCallingIdentity(origId);
5629    }
5630
5631    @Override
5632    public final void activityStopped(IBinder token, Bundle icicle,
5633            PersistableBundle persistentState, CharSequence description) {
5634        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5635
5636        // Refuse possible leaked file descriptors
5637        if (icicle != null && icicle.hasFileDescriptors()) {
5638            throw new IllegalArgumentException("File descriptors passed in Bundle");
5639        }
5640
5641        final long origId = Binder.clearCallingIdentity();
5642
5643        synchronized (this) {
5644            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5645            if (r != null) {
5646                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5647            }
5648        }
5649
5650        trimApplications();
5651
5652        Binder.restoreCallingIdentity(origId);
5653    }
5654
5655    @Override
5656    public final void activityDestroyed(IBinder token) {
5657        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5658        synchronized (this) {
5659            ActivityStack stack = ActivityRecord.getStackLocked(token);
5660            if (stack != null) {
5661                stack.activityDestroyedLocked(token);
5662            }
5663        }
5664    }
5665
5666    @Override
5667    public final void mediaResourcesReleased(IBinder token) {
5668        final long origId = Binder.clearCallingIdentity();
5669        try {
5670            synchronized (this) {
5671                ActivityStack stack = ActivityRecord.getStackLocked(token);
5672                if (stack != null) {
5673                    stack.mediaResourcesReleased(token);
5674                }
5675            }
5676        } finally {
5677            Binder.restoreCallingIdentity(origId);
5678        }
5679    }
5680
5681    @Override
5682    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5683        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5684    }
5685
5686    @Override
5687    public String getCallingPackage(IBinder token) {
5688        synchronized (this) {
5689            ActivityRecord r = getCallingRecordLocked(token);
5690            return r != null ? r.info.packageName : null;
5691        }
5692    }
5693
5694    @Override
5695    public ComponentName getCallingActivity(IBinder token) {
5696        synchronized (this) {
5697            ActivityRecord r = getCallingRecordLocked(token);
5698            return r != null ? r.intent.getComponent() : null;
5699        }
5700    }
5701
5702    private ActivityRecord getCallingRecordLocked(IBinder token) {
5703        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5704        if (r == null) {
5705            return null;
5706        }
5707        return r.resultTo;
5708    }
5709
5710    @Override
5711    public ComponentName getActivityClassForToken(IBinder token) {
5712        synchronized(this) {
5713            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5714            if (r == null) {
5715                return null;
5716            }
5717            return r.intent.getComponent();
5718        }
5719    }
5720
5721    @Override
5722    public String getPackageForToken(IBinder token) {
5723        synchronized(this) {
5724            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5725            if (r == null) {
5726                return null;
5727            }
5728            return r.packageName;
5729        }
5730    }
5731
5732    @Override
5733    public IIntentSender getIntentSender(int type,
5734            String packageName, IBinder token, String resultWho,
5735            int requestCode, Intent[] intents, String[] resolvedTypes,
5736            int flags, Bundle options, int userId) {
5737        enforceNotIsolatedCaller("getIntentSender");
5738        // Refuse possible leaked file descriptors
5739        if (intents != null) {
5740            if (intents.length < 1) {
5741                throw new IllegalArgumentException("Intents array length must be >= 1");
5742            }
5743            for (int i=0; i<intents.length; i++) {
5744                Intent intent = intents[i];
5745                if (intent != null) {
5746                    if (intent.hasFileDescriptors()) {
5747                        throw new IllegalArgumentException("File descriptors passed in Intent");
5748                    }
5749                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5750                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5751                        throw new IllegalArgumentException(
5752                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5753                    }
5754                    intents[i] = new Intent(intent);
5755                }
5756            }
5757            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5758                throw new IllegalArgumentException(
5759                        "Intent array length does not match resolvedTypes length");
5760            }
5761        }
5762        if (options != null) {
5763            if (options.hasFileDescriptors()) {
5764                throw new IllegalArgumentException("File descriptors passed in options");
5765            }
5766        }
5767
5768        synchronized(this) {
5769            int callingUid = Binder.getCallingUid();
5770            int origUserId = userId;
5771            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5772                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5773                    ALLOW_NON_FULL, "getIntentSender", null);
5774            if (origUserId == UserHandle.USER_CURRENT) {
5775                // We don't want to evaluate this until the pending intent is
5776                // actually executed.  However, we do want to always do the
5777                // security checking for it above.
5778                userId = UserHandle.USER_CURRENT;
5779            }
5780            try {
5781                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5782                    int uid = AppGlobals.getPackageManager()
5783                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5784                    if (!UserHandle.isSameApp(callingUid, uid)) {
5785                        String msg = "Permission Denial: getIntentSender() from pid="
5786                            + Binder.getCallingPid()
5787                            + ", uid=" + Binder.getCallingUid()
5788                            + ", (need uid=" + uid + ")"
5789                            + " is not allowed to send as package " + packageName;
5790                        Slog.w(TAG, msg);
5791                        throw new SecurityException(msg);
5792                    }
5793                }
5794
5795                return getIntentSenderLocked(type, packageName, callingUid, userId,
5796                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5797
5798            } catch (RemoteException e) {
5799                throw new SecurityException(e);
5800            }
5801        }
5802    }
5803
5804    IIntentSender getIntentSenderLocked(int type, String packageName,
5805            int callingUid, int userId, IBinder token, String resultWho,
5806            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5807            Bundle options) {
5808        if (DEBUG_MU)
5809            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5810        ActivityRecord activity = null;
5811        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5812            activity = ActivityRecord.isInStackLocked(token);
5813            if (activity == null) {
5814                return null;
5815            }
5816            if (activity.finishing) {
5817                return null;
5818            }
5819        }
5820
5821        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5822        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5823        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5824        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5825                |PendingIntent.FLAG_UPDATE_CURRENT);
5826
5827        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5828                type, packageName, activity, resultWho,
5829                requestCode, intents, resolvedTypes, flags, options, userId);
5830        WeakReference<PendingIntentRecord> ref;
5831        ref = mIntentSenderRecords.get(key);
5832        PendingIntentRecord rec = ref != null ? ref.get() : null;
5833        if (rec != null) {
5834            if (!cancelCurrent) {
5835                if (updateCurrent) {
5836                    if (rec.key.requestIntent != null) {
5837                        rec.key.requestIntent.replaceExtras(intents != null ?
5838                                intents[intents.length - 1] : null);
5839                    }
5840                    if (intents != null) {
5841                        intents[intents.length-1] = rec.key.requestIntent;
5842                        rec.key.allIntents = intents;
5843                        rec.key.allResolvedTypes = resolvedTypes;
5844                    } else {
5845                        rec.key.allIntents = null;
5846                        rec.key.allResolvedTypes = null;
5847                    }
5848                }
5849                return rec;
5850            }
5851            rec.canceled = true;
5852            mIntentSenderRecords.remove(key);
5853        }
5854        if (noCreate) {
5855            return rec;
5856        }
5857        rec = new PendingIntentRecord(this, key, callingUid);
5858        mIntentSenderRecords.put(key, rec.ref);
5859        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5860            if (activity.pendingResults == null) {
5861                activity.pendingResults
5862                        = new HashSet<WeakReference<PendingIntentRecord>>();
5863            }
5864            activity.pendingResults.add(rec.ref);
5865        }
5866        return rec;
5867    }
5868
5869    @Override
5870    public void cancelIntentSender(IIntentSender sender) {
5871        if (!(sender instanceof PendingIntentRecord)) {
5872            return;
5873        }
5874        synchronized(this) {
5875            PendingIntentRecord rec = (PendingIntentRecord)sender;
5876            try {
5877                int uid = AppGlobals.getPackageManager()
5878                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5879                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5880                    String msg = "Permission Denial: cancelIntentSender() from pid="
5881                        + Binder.getCallingPid()
5882                        + ", uid=" + Binder.getCallingUid()
5883                        + " is not allowed to cancel packges "
5884                        + rec.key.packageName;
5885                    Slog.w(TAG, msg);
5886                    throw new SecurityException(msg);
5887                }
5888            } catch (RemoteException e) {
5889                throw new SecurityException(e);
5890            }
5891            cancelIntentSenderLocked(rec, true);
5892        }
5893    }
5894
5895    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5896        rec.canceled = true;
5897        mIntentSenderRecords.remove(rec.key);
5898        if (cleanActivity && rec.key.activity != null) {
5899            rec.key.activity.pendingResults.remove(rec.ref);
5900        }
5901    }
5902
5903    @Override
5904    public String getPackageForIntentSender(IIntentSender pendingResult) {
5905        if (!(pendingResult instanceof PendingIntentRecord)) {
5906            return null;
5907        }
5908        try {
5909            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5910            return res.key.packageName;
5911        } catch (ClassCastException e) {
5912        }
5913        return null;
5914    }
5915
5916    @Override
5917    public int getUidForIntentSender(IIntentSender sender) {
5918        if (sender instanceof PendingIntentRecord) {
5919            try {
5920                PendingIntentRecord res = (PendingIntentRecord)sender;
5921                return res.uid;
5922            } catch (ClassCastException e) {
5923            }
5924        }
5925        return -1;
5926    }
5927
5928    @Override
5929    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5930        if (!(pendingResult instanceof PendingIntentRecord)) {
5931            return false;
5932        }
5933        try {
5934            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5935            if (res.key.allIntents == null) {
5936                return false;
5937            }
5938            for (int i=0; i<res.key.allIntents.length; i++) {
5939                Intent intent = res.key.allIntents[i];
5940                if (intent.getPackage() != null && intent.getComponent() != null) {
5941                    return false;
5942                }
5943            }
5944            return true;
5945        } catch (ClassCastException e) {
5946        }
5947        return false;
5948    }
5949
5950    @Override
5951    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5952        if (!(pendingResult instanceof PendingIntentRecord)) {
5953            return false;
5954        }
5955        try {
5956            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5957            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5958                return true;
5959            }
5960            return false;
5961        } catch (ClassCastException e) {
5962        }
5963        return false;
5964    }
5965
5966    @Override
5967    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5968        if (!(pendingResult instanceof PendingIntentRecord)) {
5969            return null;
5970        }
5971        try {
5972            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5973            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5974        } catch (ClassCastException e) {
5975        }
5976        return null;
5977    }
5978
5979    @Override
5980    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5981        if (!(pendingResult instanceof PendingIntentRecord)) {
5982            return null;
5983        }
5984        try {
5985            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5986            Intent intent = res.key.requestIntent;
5987            if (intent != null) {
5988                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5989                        || res.lastTagPrefix.equals(prefix))) {
5990                    return res.lastTag;
5991                }
5992                res.lastTagPrefix = prefix;
5993                StringBuilder sb = new StringBuilder(128);
5994                if (prefix != null) {
5995                    sb.append(prefix);
5996                }
5997                if (intent.getAction() != null) {
5998                    sb.append(intent.getAction());
5999                } else if (intent.getComponent() != null) {
6000                    intent.getComponent().appendShortString(sb);
6001                } else {
6002                    sb.append("?");
6003                }
6004                return res.lastTag = sb.toString();
6005            }
6006        } catch (ClassCastException e) {
6007        }
6008        return null;
6009    }
6010
6011    @Override
6012    public void setProcessLimit(int max) {
6013        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6014                "setProcessLimit()");
6015        synchronized (this) {
6016            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6017            mProcessLimitOverride = max;
6018        }
6019        trimApplications();
6020    }
6021
6022    @Override
6023    public int getProcessLimit() {
6024        synchronized (this) {
6025            return mProcessLimitOverride;
6026        }
6027    }
6028
6029    void foregroundTokenDied(ForegroundToken token) {
6030        synchronized (ActivityManagerService.this) {
6031            synchronized (mPidsSelfLocked) {
6032                ForegroundToken cur
6033                    = mForegroundProcesses.get(token.pid);
6034                if (cur != token) {
6035                    return;
6036                }
6037                mForegroundProcesses.remove(token.pid);
6038                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6039                if (pr == null) {
6040                    return;
6041                }
6042                pr.forcingToForeground = null;
6043                updateProcessForegroundLocked(pr, false, false);
6044            }
6045            updateOomAdjLocked();
6046        }
6047    }
6048
6049    @Override
6050    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6051        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6052                "setProcessForeground()");
6053        synchronized(this) {
6054            boolean changed = false;
6055
6056            synchronized (mPidsSelfLocked) {
6057                ProcessRecord pr = mPidsSelfLocked.get(pid);
6058                if (pr == null && isForeground) {
6059                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6060                    return;
6061                }
6062                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6063                if (oldToken != null) {
6064                    oldToken.token.unlinkToDeath(oldToken, 0);
6065                    mForegroundProcesses.remove(pid);
6066                    if (pr != null) {
6067                        pr.forcingToForeground = null;
6068                    }
6069                    changed = true;
6070                }
6071                if (isForeground && token != null) {
6072                    ForegroundToken newToken = new ForegroundToken() {
6073                        @Override
6074                        public void binderDied() {
6075                            foregroundTokenDied(this);
6076                        }
6077                    };
6078                    newToken.pid = pid;
6079                    newToken.token = token;
6080                    try {
6081                        token.linkToDeath(newToken, 0);
6082                        mForegroundProcesses.put(pid, newToken);
6083                        pr.forcingToForeground = token;
6084                        changed = true;
6085                    } catch (RemoteException e) {
6086                        // If the process died while doing this, we will later
6087                        // do the cleanup with the process death link.
6088                    }
6089                }
6090            }
6091
6092            if (changed) {
6093                updateOomAdjLocked();
6094            }
6095        }
6096    }
6097
6098    // =========================================================
6099    // PERMISSIONS
6100    // =========================================================
6101
6102    static class PermissionController extends IPermissionController.Stub {
6103        ActivityManagerService mActivityManagerService;
6104        PermissionController(ActivityManagerService activityManagerService) {
6105            mActivityManagerService = activityManagerService;
6106        }
6107
6108        @Override
6109        public boolean checkPermission(String permission, int pid, int uid) {
6110            return mActivityManagerService.checkPermission(permission, pid,
6111                    uid) == PackageManager.PERMISSION_GRANTED;
6112        }
6113    }
6114
6115    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6116        @Override
6117        public int checkComponentPermission(String permission, int pid, int uid,
6118                int owningUid, boolean exported) {
6119            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6120                    owningUid, exported);
6121        }
6122
6123        @Override
6124        public Object getAMSLock() {
6125            return ActivityManagerService.this;
6126        }
6127    }
6128
6129    /**
6130     * This can be called with or without the global lock held.
6131     */
6132    int checkComponentPermission(String permission, int pid, int uid,
6133            int owningUid, boolean exported) {
6134        // We might be performing an operation on behalf of an indirect binder
6135        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6136        // client identity accordingly before proceeding.
6137        Identity tlsIdentity = sCallerIdentity.get();
6138        if (tlsIdentity != null) {
6139            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6140                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6141            uid = tlsIdentity.uid;
6142            pid = tlsIdentity.pid;
6143        }
6144
6145        if (pid == MY_PID) {
6146            return PackageManager.PERMISSION_GRANTED;
6147        }
6148
6149        return ActivityManager.checkComponentPermission(permission, uid,
6150                owningUid, exported);
6151    }
6152
6153    /**
6154     * As the only public entry point for permissions checking, this method
6155     * can enforce the semantic that requesting a check on a null global
6156     * permission is automatically denied.  (Internally a null permission
6157     * string is used when calling {@link #checkComponentPermission} in cases
6158     * when only uid-based security is needed.)
6159     *
6160     * This can be called with or without the global lock held.
6161     */
6162    @Override
6163    public int checkPermission(String permission, int pid, int uid) {
6164        if (permission == null) {
6165            return PackageManager.PERMISSION_DENIED;
6166        }
6167        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6168    }
6169
6170    /**
6171     * Binder IPC calls go through the public entry point.
6172     * This can be called with or without the global lock held.
6173     */
6174    int checkCallingPermission(String permission) {
6175        return checkPermission(permission,
6176                Binder.getCallingPid(),
6177                UserHandle.getAppId(Binder.getCallingUid()));
6178    }
6179
6180    /**
6181     * This can be called with or without the global lock held.
6182     */
6183    void enforceCallingPermission(String permission, String func) {
6184        if (checkCallingPermission(permission)
6185                == PackageManager.PERMISSION_GRANTED) {
6186            return;
6187        }
6188
6189        String msg = "Permission Denial: " + func + " from pid="
6190                + Binder.getCallingPid()
6191                + ", uid=" + Binder.getCallingUid()
6192                + " requires " + permission;
6193        Slog.w(TAG, msg);
6194        throw new SecurityException(msg);
6195    }
6196
6197    /**
6198     * Determine if UID is holding permissions required to access {@link Uri} in
6199     * the given {@link ProviderInfo}. Final permission checking is always done
6200     * in {@link ContentProvider}.
6201     */
6202    private final boolean checkHoldingPermissionsLocked(
6203            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6204        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6205                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6206        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6207            return false;
6208        }
6209        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6210    }
6211
6212    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6213            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6214        if (pi.applicationInfo.uid == uid) {
6215            return true;
6216        } else if (!pi.exported) {
6217            return false;
6218        }
6219
6220        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6221        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6222        try {
6223            // check if target holds top-level <provider> permissions
6224            if (!readMet && pi.readPermission != null && considerUidPermissions
6225                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6226                readMet = true;
6227            }
6228            if (!writeMet && pi.writePermission != null && considerUidPermissions
6229                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6230                writeMet = true;
6231            }
6232
6233            // track if unprotected read/write is allowed; any denied
6234            // <path-permission> below removes this ability
6235            boolean allowDefaultRead = pi.readPermission == null;
6236            boolean allowDefaultWrite = pi.writePermission == null;
6237
6238            // check if target holds any <path-permission> that match uri
6239            final PathPermission[] pps = pi.pathPermissions;
6240            if (pps != null) {
6241                final String path = grantUri.uri.getPath();
6242                int i = pps.length;
6243                while (i > 0 && (!readMet || !writeMet)) {
6244                    i--;
6245                    PathPermission pp = pps[i];
6246                    if (pp.match(path)) {
6247                        if (!readMet) {
6248                            final String pprperm = pp.getReadPermission();
6249                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6250                                    + pprperm + " for " + pp.getPath()
6251                                    + ": match=" + pp.match(path)
6252                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6253                            if (pprperm != null) {
6254                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6255                                        == PERMISSION_GRANTED) {
6256                                    readMet = true;
6257                                } else {
6258                                    allowDefaultRead = false;
6259                                }
6260                            }
6261                        }
6262                        if (!writeMet) {
6263                            final String ppwperm = pp.getWritePermission();
6264                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6265                                    + ppwperm + " for " + pp.getPath()
6266                                    + ": match=" + pp.match(path)
6267                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6268                            if (ppwperm != null) {
6269                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6270                                        == PERMISSION_GRANTED) {
6271                                    writeMet = true;
6272                                } else {
6273                                    allowDefaultWrite = false;
6274                                }
6275                            }
6276                        }
6277                    }
6278                }
6279            }
6280
6281            // grant unprotected <provider> read/write, if not blocked by
6282            // <path-permission> above
6283            if (allowDefaultRead) readMet = true;
6284            if (allowDefaultWrite) writeMet = true;
6285
6286        } catch (RemoteException e) {
6287            return false;
6288        }
6289
6290        return readMet && writeMet;
6291    }
6292
6293    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6294        ProviderInfo pi = null;
6295        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6296        if (cpr != null) {
6297            pi = cpr.info;
6298        } else {
6299            try {
6300                pi = AppGlobals.getPackageManager().resolveContentProvider(
6301                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6302            } catch (RemoteException ex) {
6303            }
6304        }
6305        return pi;
6306    }
6307
6308    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6309        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6310        if (targetUris != null) {
6311            return targetUris.get(grantUri);
6312        }
6313        return null;
6314    }
6315
6316    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6317            String targetPkg, int targetUid, GrantUri grantUri) {
6318        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6319        if (targetUris == null) {
6320            targetUris = Maps.newArrayMap();
6321            mGrantedUriPermissions.put(targetUid, targetUris);
6322        }
6323
6324        UriPermission perm = targetUris.get(grantUri);
6325        if (perm == null) {
6326            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6327            targetUris.put(grantUri, perm);
6328        }
6329
6330        return perm;
6331    }
6332
6333    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6334            final int modeFlags) {
6335        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6336        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6337                : UriPermission.STRENGTH_OWNED;
6338
6339        // Root gets to do everything.
6340        if (uid == 0) {
6341            return true;
6342        }
6343
6344        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6345        if (perms == null) return false;
6346
6347        // First look for exact match
6348        final UriPermission exactPerm = perms.get(grantUri);
6349        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6350            return true;
6351        }
6352
6353        // No exact match, look for prefixes
6354        final int N = perms.size();
6355        for (int i = 0; i < N; i++) {
6356            final UriPermission perm = perms.valueAt(i);
6357            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6358                    && perm.getStrength(modeFlags) >= minStrength) {
6359                return true;
6360            }
6361        }
6362
6363        return false;
6364    }
6365
6366    @Override
6367    public int checkUriPermission(Uri uri, int pid, int uid,
6368            final int modeFlags, int userId) {
6369        enforceNotIsolatedCaller("checkUriPermission");
6370
6371        // Another redirected-binder-call permissions check as in
6372        // {@link checkComponentPermission}.
6373        Identity tlsIdentity = sCallerIdentity.get();
6374        if (tlsIdentity != null) {
6375            uid = tlsIdentity.uid;
6376            pid = tlsIdentity.pid;
6377        }
6378
6379        // Our own process gets to do everything.
6380        if (pid == MY_PID) {
6381            return PackageManager.PERMISSION_GRANTED;
6382        }
6383        synchronized (this) {
6384            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6385                    ? PackageManager.PERMISSION_GRANTED
6386                    : PackageManager.PERMISSION_DENIED;
6387        }
6388    }
6389
6390    /**
6391     * Check if the targetPkg can be granted permission to access uri by
6392     * the callingUid using the given modeFlags.  Throws a security exception
6393     * if callingUid is not allowed to do this.  Returns the uid of the target
6394     * if the URI permission grant should be performed; returns -1 if it is not
6395     * needed (for example targetPkg already has permission to access the URI).
6396     * If you already know the uid of the target, you can supply it in
6397     * lastTargetUid else set that to -1.
6398     */
6399    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6400            final int modeFlags, int lastTargetUid) {
6401        if (!Intent.isAccessUriMode(modeFlags)) {
6402            return -1;
6403        }
6404
6405        if (targetPkg != null) {
6406            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6407                    "Checking grant " + targetPkg + " permission to " + grantUri);
6408        }
6409
6410        final IPackageManager pm = AppGlobals.getPackageManager();
6411
6412        // If this is not a content: uri, we can't do anything with it.
6413        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6414            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6415                    "Can't grant URI permission for non-content URI: " + grantUri);
6416            return -1;
6417        }
6418
6419        final String authority = grantUri.uri.getAuthority();
6420        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6421        if (pi == null) {
6422            Slog.w(TAG, "No content provider found for permission check: " +
6423                    grantUri.uri.toSafeString());
6424            return -1;
6425        }
6426
6427        int targetUid = lastTargetUid;
6428        if (targetUid < 0 && targetPkg != null) {
6429            try {
6430                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6431                if (targetUid < 0) {
6432                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6433                            "Can't grant URI permission no uid for: " + targetPkg);
6434                    return -1;
6435                }
6436            } catch (RemoteException ex) {
6437                return -1;
6438            }
6439        }
6440
6441        if (targetUid >= 0) {
6442            // First...  does the target actually need this permission?
6443            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6444                // No need to grant the target this permission.
6445                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6446                        "Target " + targetPkg + " already has full permission to " + grantUri);
6447                return -1;
6448            }
6449        } else {
6450            // First...  there is no target package, so can anyone access it?
6451            boolean allowed = pi.exported;
6452            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6453                if (pi.readPermission != null) {
6454                    allowed = false;
6455                }
6456            }
6457            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6458                if (pi.writePermission != null) {
6459                    allowed = false;
6460                }
6461            }
6462            if (allowed) {
6463                return -1;
6464            }
6465        }
6466
6467        /* There is a special cross user grant if:
6468         * - The target is on another user.
6469         * - Apps on the current user can access the uri without any uid permissions.
6470         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6471         * grant uri permissions.
6472         */
6473        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6474                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6475                modeFlags, false /*without considering the uid permissions*/);
6476
6477        // Second...  is the provider allowing granting of URI permissions?
6478        if (!specialCrossUserGrant) {
6479            if (!pi.grantUriPermissions) {
6480                throw new SecurityException("Provider " + pi.packageName
6481                        + "/" + pi.name
6482                        + " does not allow granting of Uri permissions (uri "
6483                        + grantUri + ")");
6484            }
6485            if (pi.uriPermissionPatterns != null) {
6486                final int N = pi.uriPermissionPatterns.length;
6487                boolean allowed = false;
6488                for (int i=0; i<N; i++) {
6489                    if (pi.uriPermissionPatterns[i] != null
6490                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6491                        allowed = true;
6492                        break;
6493                    }
6494                }
6495                if (!allowed) {
6496                    throw new SecurityException("Provider " + pi.packageName
6497                            + "/" + pi.name
6498                            + " does not allow granting of permission to path of Uri "
6499                            + grantUri);
6500                }
6501            }
6502        }
6503
6504        // Third...  does the caller itself have permission to access
6505        // this uri?
6506        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6507            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6508                // Require they hold a strong enough Uri permission
6509                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6510                    throw new SecurityException("Uid " + callingUid
6511                            + " does not have permission to uri " + grantUri);
6512                }
6513            }
6514        }
6515        return targetUid;
6516    }
6517
6518    @Override
6519    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6520            final int modeFlags, int userId) {
6521        enforceNotIsolatedCaller("checkGrantUriPermission");
6522        synchronized(this) {
6523            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6524                    new GrantUri(userId, uri, false), modeFlags, -1);
6525        }
6526    }
6527
6528    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6529            final int modeFlags, UriPermissionOwner owner) {
6530        if (!Intent.isAccessUriMode(modeFlags)) {
6531            return;
6532        }
6533
6534        // So here we are: the caller has the assumed permission
6535        // to the uri, and the target doesn't.  Let's now give this to
6536        // the target.
6537
6538        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6539                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6540
6541        final String authority = grantUri.uri.getAuthority();
6542        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6543        if (pi == null) {
6544            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6545            return;
6546        }
6547
6548        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6549            grantUri.prefix = true;
6550        }
6551        final UriPermission perm = findOrCreateUriPermissionLocked(
6552                pi.packageName, targetPkg, targetUid, grantUri);
6553        perm.grantModes(modeFlags, owner);
6554    }
6555
6556    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6557            final int modeFlags, UriPermissionOwner owner) {
6558        if (targetPkg == null) {
6559            throw new NullPointerException("targetPkg");
6560        }
6561
6562        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6563                -1);
6564        if (targetUid < 0) {
6565            return;
6566        }
6567
6568        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6569                owner);
6570    }
6571
6572    static class NeededUriGrants extends ArrayList<GrantUri> {
6573        final String targetPkg;
6574        final int targetUid;
6575        final int flags;
6576
6577        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6578            this.targetPkg = targetPkg;
6579            this.targetUid = targetUid;
6580            this.flags = flags;
6581        }
6582    }
6583
6584    /**
6585     * Like checkGrantUriPermissionLocked, but takes an Intent.
6586     */
6587    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6588            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6589        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6590                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6591                + " clip=" + (intent != null ? intent.getClipData() : null)
6592                + " from " + intent + "; flags=0x"
6593                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6594
6595        if (targetPkg == null) {
6596            throw new NullPointerException("targetPkg");
6597        }
6598
6599        if (intent == null) {
6600            return null;
6601        }
6602        Uri data = intent.getData();
6603        ClipData clip = intent.getClipData();
6604        if (data == null && clip == null) {
6605            return null;
6606        }
6607        final IPackageManager pm = AppGlobals.getPackageManager();
6608        int targetUid;
6609        if (needed != null) {
6610            targetUid = needed.targetUid;
6611        } else {
6612            try {
6613                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6614            } catch (RemoteException ex) {
6615                return null;
6616            }
6617            if (targetUid < 0) {
6618                if (DEBUG_URI_PERMISSION) {
6619                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6620                            + " on user " + targetUserId);
6621                }
6622                return null;
6623            }
6624        }
6625        if (data != null) {
6626            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6627            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6628                    targetUid);
6629            if (targetUid > 0) {
6630                if (needed == null) {
6631                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6632                }
6633                needed.add(grantUri);
6634            }
6635        }
6636        if (clip != null) {
6637            for (int i=0; i<clip.getItemCount(); i++) {
6638                Uri uri = clip.getItemAt(i).getUri();
6639                if (uri != null) {
6640                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6641                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6642                            targetUid);
6643                    if (targetUid > 0) {
6644                        if (needed == null) {
6645                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6646                        }
6647                        needed.add(grantUri);
6648                    }
6649                } else {
6650                    Intent clipIntent = clip.getItemAt(i).getIntent();
6651                    if (clipIntent != null) {
6652                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6653                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6654                        if (newNeeded != null) {
6655                            needed = newNeeded;
6656                        }
6657                    }
6658                }
6659            }
6660        }
6661
6662        return needed;
6663    }
6664
6665    /**
6666     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6667     */
6668    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6669            UriPermissionOwner owner) {
6670        if (needed != null) {
6671            for (int i=0; i<needed.size(); i++) {
6672                GrantUri grantUri = needed.get(i);
6673                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6674                        grantUri, needed.flags, owner);
6675            }
6676        }
6677    }
6678
6679    void grantUriPermissionFromIntentLocked(int callingUid,
6680            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6681        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6682                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6683        if (needed == null) {
6684            return;
6685        }
6686
6687        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6688    }
6689
6690    @Override
6691    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6692            final int modeFlags, int userId) {
6693        enforceNotIsolatedCaller("grantUriPermission");
6694        GrantUri grantUri = new GrantUri(userId, uri, false);
6695        synchronized(this) {
6696            final ProcessRecord r = getRecordForAppLocked(caller);
6697            if (r == null) {
6698                throw new SecurityException("Unable to find app for caller "
6699                        + caller
6700                        + " when granting permission to uri " + grantUri);
6701            }
6702            if (targetPkg == null) {
6703                throw new IllegalArgumentException("null target");
6704            }
6705            if (grantUri == null) {
6706                throw new IllegalArgumentException("null uri");
6707            }
6708
6709            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6710                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6711                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6712                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6713
6714            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6715        }
6716    }
6717
6718    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6719        if (perm.modeFlags == 0) {
6720            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6721                    perm.targetUid);
6722            if (perms != null) {
6723                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6724                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6725
6726                perms.remove(perm.uri);
6727                if (perms.isEmpty()) {
6728                    mGrantedUriPermissions.remove(perm.targetUid);
6729                }
6730            }
6731        }
6732    }
6733
6734    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6735        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6736
6737        final IPackageManager pm = AppGlobals.getPackageManager();
6738        final String authority = grantUri.uri.getAuthority();
6739        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6740        if (pi == null) {
6741            Slog.w(TAG, "No content provider found for permission revoke: "
6742                    + grantUri.toSafeString());
6743            return;
6744        }
6745
6746        // Does the caller have this permission on the URI?
6747        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6748            // Right now, if you are not the original owner of the permission,
6749            // you are not allowed to revoke it.
6750            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6751                throw new SecurityException("Uid " + callingUid
6752                        + " does not have permission to uri " + grantUri);
6753            //}
6754        }
6755
6756        boolean persistChanged = false;
6757
6758        // Go through all of the permissions and remove any that match.
6759        int N = mGrantedUriPermissions.size();
6760        for (int i = 0; i < N; i++) {
6761            final int targetUid = mGrantedUriPermissions.keyAt(i);
6762            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6763
6764            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6765                final UriPermission perm = it.next();
6766                if (perm.uri.sourceUserId == grantUri.sourceUserId
6767                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6768                    if (DEBUG_URI_PERMISSION)
6769                        Slog.v(TAG,
6770                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6771                    persistChanged |= perm.revokeModes(
6772                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6773                    if (perm.modeFlags == 0) {
6774                        it.remove();
6775                    }
6776                }
6777            }
6778
6779            if (perms.isEmpty()) {
6780                mGrantedUriPermissions.remove(targetUid);
6781                N--;
6782                i--;
6783            }
6784        }
6785
6786        if (persistChanged) {
6787            schedulePersistUriGrants();
6788        }
6789    }
6790
6791    @Override
6792    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6793            int userId) {
6794        enforceNotIsolatedCaller("revokeUriPermission");
6795        synchronized(this) {
6796            final ProcessRecord r = getRecordForAppLocked(caller);
6797            if (r == null) {
6798                throw new SecurityException("Unable to find app for caller "
6799                        + caller
6800                        + " when revoking permission to uri " + uri);
6801            }
6802            if (uri == null) {
6803                Slog.w(TAG, "revokeUriPermission: null uri");
6804                return;
6805            }
6806
6807            if (!Intent.isAccessUriMode(modeFlags)) {
6808                return;
6809            }
6810
6811            final IPackageManager pm = AppGlobals.getPackageManager();
6812            final String authority = uri.getAuthority();
6813            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6814            if (pi == null) {
6815                Slog.w(TAG, "No content provider found for permission revoke: "
6816                        + uri.toSafeString());
6817                return;
6818            }
6819
6820            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6821        }
6822    }
6823
6824    /**
6825     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6826     * given package.
6827     *
6828     * @param packageName Package name to match, or {@code null} to apply to all
6829     *            packages.
6830     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6831     *            to all users.
6832     * @param persistable If persistable grants should be removed.
6833     */
6834    private void removeUriPermissionsForPackageLocked(
6835            String packageName, int userHandle, boolean persistable) {
6836        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6837            throw new IllegalArgumentException("Must narrow by either package or user");
6838        }
6839
6840        boolean persistChanged = false;
6841
6842        int N = mGrantedUriPermissions.size();
6843        for (int i = 0; i < N; i++) {
6844            final int targetUid = mGrantedUriPermissions.keyAt(i);
6845            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6846
6847            // Only inspect grants matching user
6848            if (userHandle == UserHandle.USER_ALL
6849                    || userHandle == UserHandle.getUserId(targetUid)) {
6850                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6851                    final UriPermission perm = it.next();
6852
6853                    // Only inspect grants matching package
6854                    if (packageName == null || perm.sourcePkg.equals(packageName)
6855                            || perm.targetPkg.equals(packageName)) {
6856                        persistChanged |= perm.revokeModes(
6857                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6858
6859                        // Only remove when no modes remain; any persisted grants
6860                        // will keep this alive.
6861                        if (perm.modeFlags == 0) {
6862                            it.remove();
6863                        }
6864                    }
6865                }
6866
6867                if (perms.isEmpty()) {
6868                    mGrantedUriPermissions.remove(targetUid);
6869                    N--;
6870                    i--;
6871                }
6872            }
6873        }
6874
6875        if (persistChanged) {
6876            schedulePersistUriGrants();
6877        }
6878    }
6879
6880    @Override
6881    public IBinder newUriPermissionOwner(String name) {
6882        enforceNotIsolatedCaller("newUriPermissionOwner");
6883        synchronized(this) {
6884            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6885            return owner.getExternalTokenLocked();
6886        }
6887    }
6888
6889    @Override
6890    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6891            final int modeFlags, int userId) {
6892        synchronized(this) {
6893            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6894            if (owner == null) {
6895                throw new IllegalArgumentException("Unknown owner: " + token);
6896            }
6897            if (fromUid != Binder.getCallingUid()) {
6898                if (Binder.getCallingUid() != Process.myUid()) {
6899                    // Only system code can grant URI permissions on behalf
6900                    // of other users.
6901                    throw new SecurityException("nice try");
6902                }
6903            }
6904            if (targetPkg == null) {
6905                throw new IllegalArgumentException("null target");
6906            }
6907            if (uri == null) {
6908                throw new IllegalArgumentException("null uri");
6909            }
6910
6911            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6912                    modeFlags, owner);
6913        }
6914    }
6915
6916    @Override
6917    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6918        synchronized(this) {
6919            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6920            if (owner == null) {
6921                throw new IllegalArgumentException("Unknown owner: " + token);
6922            }
6923
6924            if (uri == null) {
6925                owner.removeUriPermissionsLocked(mode);
6926            } else {
6927                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6928            }
6929        }
6930    }
6931
6932    private void schedulePersistUriGrants() {
6933        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6934            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6935                    10 * DateUtils.SECOND_IN_MILLIS);
6936        }
6937    }
6938
6939    private void writeGrantedUriPermissions() {
6940        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6941
6942        // Snapshot permissions so we can persist without lock
6943        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6944        synchronized (this) {
6945            final int size = mGrantedUriPermissions.size();
6946            for (int i = 0; i < size; i++) {
6947                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6948                for (UriPermission perm : perms.values()) {
6949                    if (perm.persistedModeFlags != 0) {
6950                        persist.add(perm.snapshot());
6951                    }
6952                }
6953            }
6954        }
6955
6956        FileOutputStream fos = null;
6957        try {
6958            fos = mGrantFile.startWrite();
6959
6960            XmlSerializer out = new FastXmlSerializer();
6961            out.setOutput(fos, "utf-8");
6962            out.startDocument(null, true);
6963            out.startTag(null, TAG_URI_GRANTS);
6964            for (UriPermission.Snapshot perm : persist) {
6965                out.startTag(null, TAG_URI_GRANT);
6966                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6967                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6968                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6969                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6970                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6971                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6972                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6973                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6974                out.endTag(null, TAG_URI_GRANT);
6975            }
6976            out.endTag(null, TAG_URI_GRANTS);
6977            out.endDocument();
6978
6979            mGrantFile.finishWrite(fos);
6980        } catch (IOException e) {
6981            if (fos != null) {
6982                mGrantFile.failWrite(fos);
6983            }
6984        }
6985    }
6986
6987    private void readGrantedUriPermissionsLocked() {
6988        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6989
6990        final long now = System.currentTimeMillis();
6991
6992        FileInputStream fis = null;
6993        try {
6994            fis = mGrantFile.openRead();
6995            final XmlPullParser in = Xml.newPullParser();
6996            in.setInput(fis, null);
6997
6998            int type;
6999            while ((type = in.next()) != END_DOCUMENT) {
7000                final String tag = in.getName();
7001                if (type == START_TAG) {
7002                    if (TAG_URI_GRANT.equals(tag)) {
7003                        final int sourceUserId;
7004                        final int targetUserId;
7005                        final int userHandle = readIntAttribute(in,
7006                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7007                        if (userHandle != UserHandle.USER_NULL) {
7008                            // For backwards compatibility.
7009                            sourceUserId = userHandle;
7010                            targetUserId = userHandle;
7011                        } else {
7012                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7013                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7014                        }
7015                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7016                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7017                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7018                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7019                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7020                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7021
7022                        // Sanity check that provider still belongs to source package
7023                        final ProviderInfo pi = getProviderInfoLocked(
7024                                uri.getAuthority(), sourceUserId);
7025                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7026                            int targetUid = -1;
7027                            try {
7028                                targetUid = AppGlobals.getPackageManager()
7029                                        .getPackageUid(targetPkg, targetUserId);
7030                            } catch (RemoteException e) {
7031                            }
7032                            if (targetUid != -1) {
7033                                final UriPermission perm = findOrCreateUriPermissionLocked(
7034                                        sourcePkg, targetPkg, targetUid,
7035                                        new GrantUri(sourceUserId, uri, prefix));
7036                                perm.initPersistedModes(modeFlags, createdTime);
7037                            }
7038                        } else {
7039                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7040                                    + " but instead found " + pi);
7041                        }
7042                    }
7043                }
7044            }
7045        } catch (FileNotFoundException e) {
7046            // Missing grants is okay
7047        } catch (IOException e) {
7048            Log.wtf(TAG, "Failed reading Uri grants", e);
7049        } catch (XmlPullParserException e) {
7050            Log.wtf(TAG, "Failed reading Uri grants", e);
7051        } finally {
7052            IoUtils.closeQuietly(fis);
7053        }
7054    }
7055
7056    @Override
7057    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7058        enforceNotIsolatedCaller("takePersistableUriPermission");
7059
7060        Preconditions.checkFlagsArgument(modeFlags,
7061                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7062
7063        synchronized (this) {
7064            final int callingUid = Binder.getCallingUid();
7065            boolean persistChanged = false;
7066            GrantUri grantUri = new GrantUri(userId, uri, false);
7067
7068            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7069                    new GrantUri(userId, uri, false));
7070            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7071                    new GrantUri(userId, uri, true));
7072
7073            final boolean exactValid = (exactPerm != null)
7074                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7075            final boolean prefixValid = (prefixPerm != null)
7076                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7077
7078            if (!(exactValid || prefixValid)) {
7079                throw new SecurityException("No persistable permission grants found for UID "
7080                        + callingUid + " and Uri " + grantUri.toSafeString());
7081            }
7082
7083            if (exactValid) {
7084                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7085            }
7086            if (prefixValid) {
7087                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7088            }
7089
7090            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7091
7092            if (persistChanged) {
7093                schedulePersistUriGrants();
7094            }
7095        }
7096    }
7097
7098    @Override
7099    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7100        enforceNotIsolatedCaller("releasePersistableUriPermission");
7101
7102        Preconditions.checkFlagsArgument(modeFlags,
7103                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7104
7105        synchronized (this) {
7106            final int callingUid = Binder.getCallingUid();
7107            boolean persistChanged = false;
7108
7109            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7110                    new GrantUri(userId, uri, false));
7111            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7112                    new GrantUri(userId, uri, true));
7113            if (exactPerm == null && prefixPerm == null) {
7114                throw new SecurityException("No permission grants found for UID " + callingUid
7115                        + " and Uri " + uri.toSafeString());
7116            }
7117
7118            if (exactPerm != null) {
7119                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7120                removeUriPermissionIfNeededLocked(exactPerm);
7121            }
7122            if (prefixPerm != null) {
7123                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7124                removeUriPermissionIfNeededLocked(prefixPerm);
7125            }
7126
7127            if (persistChanged) {
7128                schedulePersistUriGrants();
7129            }
7130        }
7131    }
7132
7133    /**
7134     * Prune any older {@link UriPermission} for the given UID until outstanding
7135     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7136     *
7137     * @return if any mutations occured that require persisting.
7138     */
7139    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7140        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7141        if (perms == null) return false;
7142        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7143
7144        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7145        for (UriPermission perm : perms.values()) {
7146            if (perm.persistedModeFlags != 0) {
7147                persisted.add(perm);
7148            }
7149        }
7150
7151        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7152        if (trimCount <= 0) return false;
7153
7154        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7155        for (int i = 0; i < trimCount; i++) {
7156            final UriPermission perm = persisted.get(i);
7157
7158            if (DEBUG_URI_PERMISSION) {
7159                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7160            }
7161
7162            perm.releasePersistableModes(~0);
7163            removeUriPermissionIfNeededLocked(perm);
7164        }
7165
7166        return true;
7167    }
7168
7169    @Override
7170    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7171            String packageName, boolean incoming) {
7172        enforceNotIsolatedCaller("getPersistedUriPermissions");
7173        Preconditions.checkNotNull(packageName, "packageName");
7174
7175        final int callingUid = Binder.getCallingUid();
7176        final IPackageManager pm = AppGlobals.getPackageManager();
7177        try {
7178            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7179            if (packageUid != callingUid) {
7180                throw new SecurityException(
7181                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7182            }
7183        } catch (RemoteException e) {
7184            throw new SecurityException("Failed to verify package name ownership");
7185        }
7186
7187        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7188        synchronized (this) {
7189            if (incoming) {
7190                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7191                        callingUid);
7192                if (perms == null) {
7193                    Slog.w(TAG, "No permission grants found for " + packageName);
7194                } else {
7195                    for (UriPermission perm : perms.values()) {
7196                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7197                            result.add(perm.buildPersistedPublicApiObject());
7198                        }
7199                    }
7200                }
7201            } else {
7202                final int size = mGrantedUriPermissions.size();
7203                for (int i = 0; i < size; i++) {
7204                    final ArrayMap<GrantUri, UriPermission> perms =
7205                            mGrantedUriPermissions.valueAt(i);
7206                    for (UriPermission perm : perms.values()) {
7207                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7208                            result.add(perm.buildPersistedPublicApiObject());
7209                        }
7210                    }
7211                }
7212            }
7213        }
7214        return new ParceledListSlice<android.content.UriPermission>(result);
7215    }
7216
7217    @Override
7218    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7219        synchronized (this) {
7220            ProcessRecord app =
7221                who != null ? getRecordForAppLocked(who) : null;
7222            if (app == null) return;
7223
7224            Message msg = Message.obtain();
7225            msg.what = WAIT_FOR_DEBUGGER_MSG;
7226            msg.obj = app;
7227            msg.arg1 = waiting ? 1 : 0;
7228            mHandler.sendMessage(msg);
7229        }
7230    }
7231
7232    @Override
7233    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7234        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7235        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7236        outInfo.availMem = Process.getFreeMemory();
7237        outInfo.totalMem = Process.getTotalMemory();
7238        outInfo.threshold = homeAppMem;
7239        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7240        outInfo.hiddenAppThreshold = cachedAppMem;
7241        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7242                ProcessList.SERVICE_ADJ);
7243        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7244                ProcessList.VISIBLE_APP_ADJ);
7245        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7246                ProcessList.FOREGROUND_APP_ADJ);
7247    }
7248
7249    // =========================================================
7250    // TASK MANAGEMENT
7251    // =========================================================
7252
7253    @Override
7254    public List<IAppTask> getAppTasks() {
7255        final PackageManager pm = mContext.getPackageManager();
7256        int callingUid = Binder.getCallingUid();
7257        long ident = Binder.clearCallingIdentity();
7258
7259        // Compose the list of packages for this id to test against
7260        HashSet<String> packages = new HashSet<String>();
7261        String[] uidPackages = pm.getPackagesForUid(callingUid);
7262        for (int i = 0; i < uidPackages.length; i++) {
7263            packages.add(uidPackages[i]);
7264        }
7265
7266        synchronized(this) {
7267            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7268            try {
7269                if (localLOGV) Slog.v(TAG, "getAppTasks");
7270
7271                final int N = mRecentTasks.size();
7272                for (int i = 0; i < N; i++) {
7273                    TaskRecord tr = mRecentTasks.get(i);
7274                    // Skip tasks that are not created by the caller
7275                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7276                        ActivityManager.RecentTaskInfo taskInfo =
7277                                createRecentTaskInfoFromTaskRecord(tr);
7278                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7279                        list.add(taskImpl);
7280                    }
7281                }
7282            } finally {
7283                Binder.restoreCallingIdentity(ident);
7284            }
7285            return list;
7286        }
7287    }
7288
7289    @Override
7290    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7291        final int callingUid = Binder.getCallingUid();
7292        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7293
7294        synchronized(this) {
7295            if (localLOGV) Slog.v(
7296                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7297
7298            final boolean allowed = checkCallingPermission(
7299                    android.Manifest.permission.GET_TASKS)
7300                    == PackageManager.PERMISSION_GRANTED;
7301            if (!allowed) {
7302                Slog.w(TAG, "getTasks: caller " + callingUid
7303                        + " does not hold GET_TASKS; limiting output");
7304            }
7305
7306            // TODO: Improve with MRU list from all ActivityStacks.
7307            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7308        }
7309
7310        return list;
7311    }
7312
7313    TaskRecord getMostRecentTask() {
7314        return mRecentTasks.get(0);
7315    }
7316
7317    /**
7318     * Creates a new RecentTaskInfo from a TaskRecord.
7319     */
7320    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7321        // Update the task description to reflect any changes in the task stack
7322        tr.updateTaskDescription();
7323
7324        // Compose the recent task info
7325        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7326        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7327        rti.persistentId = tr.taskId;
7328        rti.baseIntent = new Intent(tr.getBaseIntent());
7329        rti.origActivity = tr.origActivity;
7330        rti.description = tr.lastDescription;
7331        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7332        rti.userId = tr.userId;
7333        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7334        rti.firstActiveTime = tr.firstActiveTime;
7335        rti.lastActiveTime = tr.lastActiveTime;
7336        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7337        return rti;
7338    }
7339
7340    @Override
7341    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7342        final int callingUid = Binder.getCallingUid();
7343        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7344                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7345
7346        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7347        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7348        synchronized (this) {
7349            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7350                    == PackageManager.PERMISSION_GRANTED;
7351            if (!allowed) {
7352                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7353                        + " does not hold GET_TASKS; limiting output");
7354            }
7355            final boolean detailed = checkCallingPermission(
7356                    android.Manifest.permission.GET_DETAILED_TASKS)
7357                    == PackageManager.PERMISSION_GRANTED;
7358
7359            IPackageManager pm = AppGlobals.getPackageManager();
7360
7361            final int N = mRecentTasks.size();
7362            ArrayList<ActivityManager.RecentTaskInfo> res
7363                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7364                            maxNum < N ? maxNum : N);
7365
7366            final Set<Integer> includedUsers;
7367            if (includeProfiles) {
7368                includedUsers = getProfileIdsLocked(userId);
7369            } else {
7370                includedUsers = new HashSet<Integer>();
7371            }
7372            includedUsers.add(Integer.valueOf(userId));
7373
7374            // Regroup affiliated tasks together.
7375            for (int i = 0; i < N; ) {
7376                TaskRecord task = mRecentTasks.remove(i);
7377                if (mTmpRecents.contains(task)) {
7378                    continue;
7379                }
7380                int affiliatedTaskId = task.mAffiliatedTaskId;
7381                while (true) {
7382                    TaskRecord next = task.mNextAffiliate;
7383                    if (next == null) {
7384                        break;
7385                    }
7386                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7387                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7388                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7389                        task.setNextAffiliate(null);
7390                        if (next.mPrevAffiliate == task) {
7391                            next.setPrevAffiliate(null);
7392                        }
7393                        break;
7394                    }
7395                    if (next.mPrevAffiliate != task) {
7396                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7397                                next.mPrevAffiliate + " task=" + task);
7398                        next.setPrevAffiliate(null);
7399                        break;
7400                    }
7401                    if (!mRecentTasks.contains(next)) {
7402                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7403                        task.setNextAffiliate(null);
7404                        if (next.mPrevAffiliate == task) {
7405                            next.setPrevAffiliate(null);
7406                        }
7407                        break;
7408                    }
7409                    task = next;
7410                }
7411                // task is now the end of the list
7412                do {
7413                    mRecentTasks.remove(task);
7414                    mRecentTasks.add(i++, task);
7415                    mTmpRecents.add(task);
7416                } while ((task = task.mPrevAffiliate) != null);
7417            }
7418            mTmpRecents.clear();
7419            // mRecentTasks is now in sorted, affiliated order.
7420
7421            for (int i=0; i<N && maxNum > 0; i++) {
7422                TaskRecord tr = mRecentTasks.get(i);
7423                // Only add calling user or related users recent tasks
7424                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7425
7426                // Return the entry if desired by the caller.  We always return
7427                // the first entry, because callers always expect this to be the
7428                // foreground app.  We may filter others if the caller has
7429                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7430                // we should exclude the entry.
7431
7432                if (i == 0
7433                        || withExcluded
7434                        || (tr.intent == null)
7435                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7436                                == 0)) {
7437                    if (!allowed) {
7438                        // If the caller doesn't have the GET_TASKS permission, then only
7439                        // allow them to see a small subset of tasks -- their own and home.
7440                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7441                            continue;
7442                        }
7443                    }
7444                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7445                        // Don't include auto remove tasks that are finished or finishing.
7446                        continue;
7447                    }
7448
7449                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7450                    if (!detailed) {
7451                        rti.baseIntent.replaceExtras((Bundle)null);
7452                    }
7453
7454                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7455                        // Check whether this activity is currently available.
7456                        try {
7457                            if (rti.origActivity != null) {
7458                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7459                                        == null) {
7460                                    continue;
7461                                }
7462                            } else if (rti.baseIntent != null) {
7463                                if (pm.queryIntentActivities(rti.baseIntent,
7464                                        null, 0, userId) == null) {
7465                                    continue;
7466                                }
7467                            }
7468                        } catch (RemoteException e) {
7469                            // Will never happen.
7470                        }
7471                    }
7472
7473                    res.add(rti);
7474                    maxNum--;
7475                }
7476            }
7477            return res;
7478        }
7479    }
7480
7481    private TaskRecord recentTaskForIdLocked(int id) {
7482        final int N = mRecentTasks.size();
7483            for (int i=0; i<N; i++) {
7484                TaskRecord tr = mRecentTasks.get(i);
7485                if (tr.taskId == id) {
7486                    return tr;
7487                }
7488            }
7489            return null;
7490    }
7491
7492    @Override
7493    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7494        synchronized (this) {
7495            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7496                    "getTaskThumbnail()");
7497            TaskRecord tr = recentTaskForIdLocked(id);
7498            if (tr != null) {
7499                return tr.getTaskThumbnailLocked();
7500            }
7501        }
7502        return null;
7503    }
7504
7505    @Override
7506    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7507        synchronized (this) {
7508            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7509            if (r != null) {
7510                r.taskDescription = td;
7511                r.task.updateTaskDescription();
7512            }
7513        }
7514    }
7515
7516    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7517        if (!pr.killedByAm) {
7518            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7519            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7520                    pr.processName, pr.setAdj, reason);
7521            pr.killedByAm = true;
7522            Process.killProcessQuiet(pr.pid);
7523            Process.killProcessGroup(pr.info.uid, pr.pid);
7524        }
7525    }
7526
7527    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7528        tr.disposeThumbnail();
7529        mRecentTasks.remove(tr);
7530        tr.closeRecentsChain();
7531        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7532        Intent baseIntent = new Intent(
7533                tr.intent != null ? tr.intent : tr.affinityIntent);
7534        ComponentName component = baseIntent.getComponent();
7535        if (component == null) {
7536            Slog.w(TAG, "Now component for base intent of task: " + tr);
7537            return;
7538        }
7539
7540        // Find any running services associated with this app.
7541        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7542
7543        if (killProcesses) {
7544            // Find any running processes associated with this app.
7545            final String pkg = component.getPackageName();
7546            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7547            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7548            for (int i=0; i<pmap.size(); i++) {
7549                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7550                for (int j=0; j<uids.size(); j++) {
7551                    ProcessRecord proc = uids.valueAt(j);
7552                    if (proc.userId != tr.userId) {
7553                        continue;
7554                    }
7555                    if (!proc.pkgList.containsKey(pkg)) {
7556                        continue;
7557                    }
7558                    procs.add(proc);
7559                }
7560            }
7561
7562            // Kill the running processes.
7563            for (int i=0; i<procs.size(); i++) {
7564                ProcessRecord pr = procs.get(i);
7565                if (pr == mHomeProcess) {
7566                    // Don't kill the home process along with tasks from the same package.
7567                    continue;
7568                }
7569                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7570                    killUnneededProcessLocked(pr, "remove task");
7571                } else {
7572                    pr.waitingToKill = "remove task";
7573                }
7574            }
7575        }
7576    }
7577
7578    /**
7579     * Removes the task with the specified task id.
7580     *
7581     * @param taskId Identifier of the task to be removed.
7582     * @param flags Additional operational flags.  May be 0 or
7583     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7584     * @return Returns true if the given task was found and removed.
7585     */
7586    private boolean removeTaskByIdLocked(int taskId, int flags) {
7587        TaskRecord tr = recentTaskForIdLocked(taskId);
7588        if (tr != null) {
7589            tr.removeTaskActivitiesLocked();
7590            cleanUpRemovedTaskLocked(tr, flags);
7591            if (tr.isPersistable) {
7592                notifyTaskPersisterLocked(tr, true);
7593            }
7594            return true;
7595        }
7596        return false;
7597    }
7598
7599    @Override
7600    public boolean removeTask(int taskId, int flags) {
7601        synchronized (this) {
7602            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7603                    "removeTask()");
7604            long ident = Binder.clearCallingIdentity();
7605            try {
7606                return removeTaskByIdLocked(taskId, flags);
7607            } finally {
7608                Binder.restoreCallingIdentity(ident);
7609            }
7610        }
7611    }
7612
7613    /**
7614     * TODO: Add mController hook
7615     */
7616    @Override
7617    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7618        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7619                "moveTaskToFront()");
7620
7621        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7622        synchronized(this) {
7623            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7624                    Binder.getCallingUid(), "Task to front")) {
7625                ActivityOptions.abort(options);
7626                return;
7627            }
7628            final long origId = Binder.clearCallingIdentity();
7629            try {
7630                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7631                if (task == null) {
7632                    return;
7633                }
7634                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7635                    mStackSupervisor.showLockTaskToast();
7636                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7637                    return;
7638                }
7639                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7640                if (prev != null && prev.isRecentsActivity()) {
7641                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7642                }
7643                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7644            } finally {
7645                Binder.restoreCallingIdentity(origId);
7646            }
7647            ActivityOptions.abort(options);
7648        }
7649    }
7650
7651    @Override
7652    public void moveTaskToBack(int taskId) {
7653        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7654                "moveTaskToBack()");
7655
7656        synchronized(this) {
7657            TaskRecord tr = recentTaskForIdLocked(taskId);
7658            if (tr != null) {
7659                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7660                ActivityStack stack = tr.stack;
7661                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7662                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7663                            Binder.getCallingUid(), "Task to back")) {
7664                        return;
7665                    }
7666                }
7667                final long origId = Binder.clearCallingIdentity();
7668                try {
7669                    stack.moveTaskToBackLocked(taskId, null);
7670                } finally {
7671                    Binder.restoreCallingIdentity(origId);
7672                }
7673            }
7674        }
7675    }
7676
7677    /**
7678     * Moves an activity, and all of the other activities within the same task, to the bottom
7679     * of the history stack.  The activity's order within the task is unchanged.
7680     *
7681     * @param token A reference to the activity we wish to move
7682     * @param nonRoot If false then this only works if the activity is the root
7683     *                of a task; if true it will work for any activity in a task.
7684     * @return Returns true if the move completed, false if not.
7685     */
7686    @Override
7687    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7688        enforceNotIsolatedCaller("moveActivityTaskToBack");
7689        synchronized(this) {
7690            final long origId = Binder.clearCallingIdentity();
7691            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7692            if (taskId >= 0) {
7693                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7694            }
7695            Binder.restoreCallingIdentity(origId);
7696        }
7697        return false;
7698    }
7699
7700    @Override
7701    public void moveTaskBackwards(int task) {
7702        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7703                "moveTaskBackwards()");
7704
7705        synchronized(this) {
7706            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7707                    Binder.getCallingUid(), "Task backwards")) {
7708                return;
7709            }
7710            final long origId = Binder.clearCallingIdentity();
7711            moveTaskBackwardsLocked(task);
7712            Binder.restoreCallingIdentity(origId);
7713        }
7714    }
7715
7716    private final void moveTaskBackwardsLocked(int task) {
7717        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7718    }
7719
7720    @Override
7721    public IBinder getHomeActivityToken() throws RemoteException {
7722        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7723                "getHomeActivityToken()");
7724        synchronized (this) {
7725            return mStackSupervisor.getHomeActivityToken();
7726        }
7727    }
7728
7729    @Override
7730    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7731            IActivityContainerCallback callback) throws RemoteException {
7732        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7733                "createActivityContainer()");
7734        synchronized (this) {
7735            if (parentActivityToken == null) {
7736                throw new IllegalArgumentException("parent token must not be null");
7737            }
7738            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7739            if (r == null) {
7740                return null;
7741            }
7742            if (callback == null) {
7743                throw new IllegalArgumentException("callback must not be null");
7744            }
7745            return mStackSupervisor.createActivityContainer(r, callback);
7746        }
7747    }
7748
7749    @Override
7750    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7751        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7752                "deleteActivityContainer()");
7753        synchronized (this) {
7754            mStackSupervisor.deleteActivityContainer(container);
7755        }
7756    }
7757
7758    @Override
7759    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7760            throws RemoteException {
7761        synchronized (this) {
7762            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7763            if (stack != null) {
7764                return stack.mActivityContainer;
7765            }
7766            return null;
7767        }
7768    }
7769
7770    @Override
7771    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7772        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7773                "moveTaskToStack()");
7774        if (stackId == HOME_STACK_ID) {
7775            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7776                    new RuntimeException("here").fillInStackTrace());
7777        }
7778        synchronized (this) {
7779            long ident = Binder.clearCallingIdentity();
7780            try {
7781                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7782                        + stackId + " toTop=" + toTop);
7783                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7784            } finally {
7785                Binder.restoreCallingIdentity(ident);
7786            }
7787        }
7788    }
7789
7790    @Override
7791    public void resizeStack(int stackBoxId, Rect bounds) {
7792        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7793                "resizeStackBox()");
7794        long ident = Binder.clearCallingIdentity();
7795        try {
7796            mWindowManager.resizeStack(stackBoxId, bounds);
7797        } finally {
7798            Binder.restoreCallingIdentity(ident);
7799        }
7800    }
7801
7802    @Override
7803    public List<StackInfo> getAllStackInfos() {
7804        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7805                "getAllStackInfos()");
7806        long ident = Binder.clearCallingIdentity();
7807        try {
7808            synchronized (this) {
7809                return mStackSupervisor.getAllStackInfosLocked();
7810            }
7811        } finally {
7812            Binder.restoreCallingIdentity(ident);
7813        }
7814    }
7815
7816    @Override
7817    public StackInfo getStackInfo(int stackId) {
7818        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7819                "getStackInfo()");
7820        long ident = Binder.clearCallingIdentity();
7821        try {
7822            synchronized (this) {
7823                return mStackSupervisor.getStackInfoLocked(stackId);
7824            }
7825        } finally {
7826            Binder.restoreCallingIdentity(ident);
7827        }
7828    }
7829
7830    @Override
7831    public boolean isInHomeStack(int taskId) {
7832        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7833                "getStackInfo()");
7834        long ident = Binder.clearCallingIdentity();
7835        try {
7836            synchronized (this) {
7837                TaskRecord tr = recentTaskForIdLocked(taskId);
7838                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7839            }
7840        } finally {
7841            Binder.restoreCallingIdentity(ident);
7842        }
7843    }
7844
7845    @Override
7846    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7847        synchronized(this) {
7848            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7849        }
7850    }
7851
7852    private boolean isLockTaskAuthorized(String pkg) {
7853        final DevicePolicyManager dpm = (DevicePolicyManager)
7854                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7855        try {
7856            int uid = mContext.getPackageManager().getPackageUid(pkg,
7857                    Binder.getCallingUserHandle().getIdentifier());
7858            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7859        } catch (NameNotFoundException e) {
7860            return false;
7861        }
7862    }
7863
7864    void startLockTaskMode(TaskRecord task) {
7865        final String pkg;
7866        synchronized (this) {
7867            pkg = task.intent.getComponent().getPackageName();
7868        }
7869        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7870        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7871            final TaskRecord taskRecord = task;
7872            mHandler.post(new Runnable() {
7873                @Override
7874                public void run() {
7875                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7876                }
7877            });
7878            return;
7879        }
7880        long ident = Binder.clearCallingIdentity();
7881        try {
7882            synchronized (this) {
7883                // Since we lost lock on task, make sure it is still there.
7884                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7885                if (task != null) {
7886                    if (!isSystemInitiated
7887                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7888                        throw new IllegalArgumentException("Invalid task, not in foreground");
7889                    }
7890                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7891                }
7892            }
7893        } finally {
7894            Binder.restoreCallingIdentity(ident);
7895        }
7896    }
7897
7898    @Override
7899    public void startLockTaskMode(int taskId) {
7900        final TaskRecord task;
7901        long ident = Binder.clearCallingIdentity();
7902        try {
7903            synchronized (this) {
7904                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7905            }
7906        } finally {
7907            Binder.restoreCallingIdentity(ident);
7908        }
7909        if (task != null) {
7910            startLockTaskMode(task);
7911        }
7912    }
7913
7914    @Override
7915    public void startLockTaskMode(IBinder token) {
7916        final TaskRecord task;
7917        long ident = Binder.clearCallingIdentity();
7918        try {
7919            synchronized (this) {
7920                final ActivityRecord r = ActivityRecord.forToken(token);
7921                if (r == null) {
7922                    return;
7923                }
7924                task = r.task;
7925            }
7926        } finally {
7927            Binder.restoreCallingIdentity(ident);
7928        }
7929        if (task != null) {
7930            startLockTaskMode(task);
7931        }
7932    }
7933
7934    @Override
7935    public void startLockTaskModeOnCurrent() throws RemoteException {
7936        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7937        ActivityRecord r = null;
7938        synchronized (this) {
7939            r = mStackSupervisor.topRunningActivityLocked();
7940        }
7941        startLockTaskMode(r.task);
7942    }
7943
7944    @Override
7945    public void stopLockTaskMode() {
7946        // Verify that the user matches the package of the intent for the TaskRecord
7947        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7948        // and stopLockTaskMode.
7949        final int callingUid = Binder.getCallingUid();
7950        if (callingUid != Process.SYSTEM_UID) {
7951            try {
7952                String pkg =
7953                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7954                int uid = mContext.getPackageManager().getPackageUid(pkg,
7955                        Binder.getCallingUserHandle().getIdentifier());
7956                if (uid != callingUid) {
7957                    throw new SecurityException("Invalid uid, expected " + uid);
7958                }
7959            } catch (NameNotFoundException e) {
7960                Log.d(TAG, "stopLockTaskMode " + e);
7961                return;
7962            }
7963        }
7964        long ident = Binder.clearCallingIdentity();
7965        try {
7966            Log.d(TAG, "stopLockTaskMode");
7967            // Stop lock task
7968            synchronized (this) {
7969                mStackSupervisor.setLockTaskModeLocked(null, false);
7970            }
7971        } finally {
7972            Binder.restoreCallingIdentity(ident);
7973        }
7974    }
7975
7976    @Override
7977    public void stopLockTaskModeOnCurrent() throws RemoteException {
7978        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7979        long ident = Binder.clearCallingIdentity();
7980        try {
7981            stopLockTaskMode();
7982        } finally {
7983            Binder.restoreCallingIdentity(ident);
7984        }
7985    }
7986
7987    @Override
7988    public boolean isInLockTaskMode() {
7989        synchronized (this) {
7990            return mStackSupervisor.isInLockTaskMode();
7991        }
7992    }
7993
7994    // =========================================================
7995    // CONTENT PROVIDERS
7996    // =========================================================
7997
7998    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7999        List<ProviderInfo> providers = null;
8000        try {
8001            providers = AppGlobals.getPackageManager().
8002                queryContentProviders(app.processName, app.uid,
8003                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8004        } catch (RemoteException ex) {
8005        }
8006        if (DEBUG_MU)
8007            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8008        int userId = app.userId;
8009        if (providers != null) {
8010            int N = providers.size();
8011            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8012            for (int i=0; i<N; i++) {
8013                ProviderInfo cpi =
8014                    (ProviderInfo)providers.get(i);
8015                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8016                        cpi.name, cpi.flags);
8017                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8018                    // This is a singleton provider, but a user besides the
8019                    // default user is asking to initialize a process it runs
8020                    // in...  well, no, it doesn't actually run in this process,
8021                    // it runs in the process of the default user.  Get rid of it.
8022                    providers.remove(i);
8023                    N--;
8024                    i--;
8025                    continue;
8026                }
8027
8028                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8029                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8030                if (cpr == null) {
8031                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8032                    mProviderMap.putProviderByClass(comp, cpr);
8033                }
8034                if (DEBUG_MU)
8035                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8036                app.pubProviders.put(cpi.name, cpr);
8037                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8038                    // Don't add this if it is a platform component that is marked
8039                    // to run in multiple processes, because this is actually
8040                    // part of the framework so doesn't make sense to track as a
8041                    // separate apk in the process.
8042                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8043                            mProcessStats);
8044                }
8045                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8046            }
8047        }
8048        return providers;
8049    }
8050
8051    /**
8052     * Check if {@link ProcessRecord} has a possible chance at accessing the
8053     * given {@link ProviderInfo}. Final permission checking is always done
8054     * in {@link ContentProvider}.
8055     */
8056    private final String checkContentProviderPermissionLocked(
8057            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8058        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8059        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8060        boolean checkedGrants = false;
8061        if (checkUser) {
8062            // Looking for cross-user grants before enforcing the typical cross-users permissions
8063            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8064            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8065                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8066                    return null;
8067                }
8068                checkedGrants = true;
8069            }
8070            userId = handleIncomingUser(callingPid, callingUid, userId,
8071                    false, ALLOW_NON_FULL,
8072                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8073            if (userId != tmpTargetUserId) {
8074                // When we actually went to determine the final targer user ID, this ended
8075                // up different than our initial check for the authority.  This is because
8076                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8077                // SELF.  So we need to re-check the grants again.
8078                checkedGrants = false;
8079            }
8080        }
8081        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8082                cpi.applicationInfo.uid, cpi.exported)
8083                == PackageManager.PERMISSION_GRANTED) {
8084            return null;
8085        }
8086        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8087                cpi.applicationInfo.uid, cpi.exported)
8088                == PackageManager.PERMISSION_GRANTED) {
8089            return null;
8090        }
8091
8092        PathPermission[] pps = cpi.pathPermissions;
8093        if (pps != null) {
8094            int i = pps.length;
8095            while (i > 0) {
8096                i--;
8097                PathPermission pp = pps[i];
8098                String pprperm = pp.getReadPermission();
8099                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8100                        cpi.applicationInfo.uid, cpi.exported)
8101                        == PackageManager.PERMISSION_GRANTED) {
8102                    return null;
8103                }
8104                String ppwperm = pp.getWritePermission();
8105                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8106                        cpi.applicationInfo.uid, cpi.exported)
8107                        == PackageManager.PERMISSION_GRANTED) {
8108                    return null;
8109                }
8110            }
8111        }
8112        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8113            return null;
8114        }
8115
8116        String msg;
8117        if (!cpi.exported) {
8118            msg = "Permission Denial: opening provider " + cpi.name
8119                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8120                    + ", uid=" + callingUid + ") that is not exported from uid "
8121                    + cpi.applicationInfo.uid;
8122        } else {
8123            msg = "Permission Denial: opening provider " + cpi.name
8124                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8125                    + ", uid=" + callingUid + ") requires "
8126                    + cpi.readPermission + " or " + cpi.writePermission;
8127        }
8128        Slog.w(TAG, msg);
8129        return msg;
8130    }
8131
8132    /**
8133     * Returns if the ContentProvider has granted a uri to callingUid
8134     */
8135    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8136        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8137        if (perms != null) {
8138            for (int i=perms.size()-1; i>=0; i--) {
8139                GrantUri grantUri = perms.keyAt(i);
8140                if (grantUri.sourceUserId == userId || !checkUser) {
8141                    if (matchesProvider(grantUri.uri, cpi)) {
8142                        return true;
8143                    }
8144                }
8145            }
8146        }
8147        return false;
8148    }
8149
8150    /**
8151     * Returns true if the uri authority is one of the authorities specified in the provider.
8152     */
8153    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8154        String uriAuth = uri.getAuthority();
8155        String cpiAuth = cpi.authority;
8156        if (cpiAuth.indexOf(';') == -1) {
8157            return cpiAuth.equals(uriAuth);
8158        }
8159        String[] cpiAuths = cpiAuth.split(";");
8160        int length = cpiAuths.length;
8161        for (int i = 0; i < length; i++) {
8162            if (cpiAuths[i].equals(uriAuth)) return true;
8163        }
8164        return false;
8165    }
8166
8167    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8168            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8169        if (r != null) {
8170            for (int i=0; i<r.conProviders.size(); i++) {
8171                ContentProviderConnection conn = r.conProviders.get(i);
8172                if (conn.provider == cpr) {
8173                    if (DEBUG_PROVIDER) Slog.v(TAG,
8174                            "Adding provider requested by "
8175                            + r.processName + " from process "
8176                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8177                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8178                    if (stable) {
8179                        conn.stableCount++;
8180                        conn.numStableIncs++;
8181                    } else {
8182                        conn.unstableCount++;
8183                        conn.numUnstableIncs++;
8184                    }
8185                    return conn;
8186                }
8187            }
8188            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8189            if (stable) {
8190                conn.stableCount = 1;
8191                conn.numStableIncs = 1;
8192            } else {
8193                conn.unstableCount = 1;
8194                conn.numUnstableIncs = 1;
8195            }
8196            cpr.connections.add(conn);
8197            r.conProviders.add(conn);
8198            return conn;
8199        }
8200        cpr.addExternalProcessHandleLocked(externalProcessToken);
8201        return null;
8202    }
8203
8204    boolean decProviderCountLocked(ContentProviderConnection conn,
8205            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8206        if (conn != null) {
8207            cpr = conn.provider;
8208            if (DEBUG_PROVIDER) Slog.v(TAG,
8209                    "Removing provider requested by "
8210                    + conn.client.processName + " from process "
8211                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8212                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8213            if (stable) {
8214                conn.stableCount--;
8215            } else {
8216                conn.unstableCount--;
8217            }
8218            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8219                cpr.connections.remove(conn);
8220                conn.client.conProviders.remove(conn);
8221                return true;
8222            }
8223            return false;
8224        }
8225        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8226        return false;
8227    }
8228
8229    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8230            String name, IBinder token, boolean stable, int userId) {
8231        ContentProviderRecord cpr;
8232        ContentProviderConnection conn = null;
8233        ProviderInfo cpi = null;
8234
8235        synchronized(this) {
8236            ProcessRecord r = null;
8237            if (caller != null) {
8238                r = getRecordForAppLocked(caller);
8239                if (r == null) {
8240                    throw new SecurityException(
8241                            "Unable to find app for caller " + caller
8242                          + " (pid=" + Binder.getCallingPid()
8243                          + ") when getting content provider " + name);
8244                }
8245            }
8246
8247            boolean checkCrossUser = true;
8248
8249            // First check if this content provider has been published...
8250            cpr = mProviderMap.getProviderByName(name, userId);
8251            // If that didn't work, check if it exists for user 0 and then
8252            // verify that it's a singleton provider before using it.
8253            if (cpr == null && userId != UserHandle.USER_OWNER) {
8254                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8255                if (cpr != null) {
8256                    cpi = cpr.info;
8257                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8258                            cpi.name, cpi.flags)
8259                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8260                        userId = UserHandle.USER_OWNER;
8261                        checkCrossUser = false;
8262                    } else {
8263                        cpr = null;
8264                        cpi = null;
8265                    }
8266                }
8267            }
8268
8269            boolean providerRunning = cpr != null;
8270            if (providerRunning) {
8271                cpi = cpr.info;
8272                String msg;
8273                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8274                        != null) {
8275                    throw new SecurityException(msg);
8276                }
8277
8278                if (r != null && cpr.canRunHere(r)) {
8279                    // This provider has been published or is in the process
8280                    // of being published...  but it is also allowed to run
8281                    // in the caller's process, so don't make a connection
8282                    // and just let the caller instantiate its own instance.
8283                    ContentProviderHolder holder = cpr.newHolder(null);
8284                    // don't give caller the provider object, it needs
8285                    // to make its own.
8286                    holder.provider = null;
8287                    return holder;
8288                }
8289
8290                final long origId = Binder.clearCallingIdentity();
8291
8292                // In this case the provider instance already exists, so we can
8293                // return it right away.
8294                conn = incProviderCountLocked(r, cpr, token, stable);
8295                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8296                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8297                        // If this is a perceptible app accessing the provider,
8298                        // make sure to count it as being accessed and thus
8299                        // back up on the LRU list.  This is good because
8300                        // content providers are often expensive to start.
8301                        updateLruProcessLocked(cpr.proc, false, null);
8302                    }
8303                }
8304
8305                if (cpr.proc != null) {
8306                    if (false) {
8307                        if (cpr.name.flattenToShortString().equals(
8308                                "com.android.providers.calendar/.CalendarProvider2")) {
8309                            Slog.v(TAG, "****************** KILLING "
8310                                + cpr.name.flattenToShortString());
8311                            Process.killProcess(cpr.proc.pid);
8312                        }
8313                    }
8314                    boolean success = updateOomAdjLocked(cpr.proc);
8315                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8316                    // NOTE: there is still a race here where a signal could be
8317                    // pending on the process even though we managed to update its
8318                    // adj level.  Not sure what to do about this, but at least
8319                    // the race is now smaller.
8320                    if (!success) {
8321                        // Uh oh...  it looks like the provider's process
8322                        // has been killed on us.  We need to wait for a new
8323                        // process to be started, and make sure its death
8324                        // doesn't kill our process.
8325                        Slog.i(TAG,
8326                                "Existing provider " + cpr.name.flattenToShortString()
8327                                + " is crashing; detaching " + r);
8328                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8329                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8330                        if (!lastRef) {
8331                            // This wasn't the last ref our process had on
8332                            // the provider...  we have now been killed, bail.
8333                            return null;
8334                        }
8335                        providerRunning = false;
8336                        conn = null;
8337                    }
8338                }
8339
8340                Binder.restoreCallingIdentity(origId);
8341            }
8342
8343            boolean singleton;
8344            if (!providerRunning) {
8345                try {
8346                    cpi = AppGlobals.getPackageManager().
8347                        resolveContentProvider(name,
8348                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8349                } catch (RemoteException ex) {
8350                }
8351                if (cpi == null) {
8352                    return null;
8353                }
8354                // If the provider is a singleton AND
8355                // (it's a call within the same user || the provider is a
8356                // privileged app)
8357                // Then allow connecting to the singleton provider
8358                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8359                        cpi.name, cpi.flags)
8360                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8361                if (singleton) {
8362                    userId = UserHandle.USER_OWNER;
8363                }
8364                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8365
8366                String msg;
8367                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8368                        != null) {
8369                    throw new SecurityException(msg);
8370                }
8371
8372                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8373                        && !cpi.processName.equals("system")) {
8374                    // If this content provider does not run in the system
8375                    // process, and the system is not yet ready to run other
8376                    // processes, then fail fast instead of hanging.
8377                    throw new IllegalArgumentException(
8378                            "Attempt to launch content provider before system ready");
8379                }
8380
8381                // Make sure that the user who owns this provider is started.  If not,
8382                // we don't want to allow it to run.
8383                if (mStartedUsers.get(userId) == null) {
8384                    Slog.w(TAG, "Unable to launch app "
8385                            + cpi.applicationInfo.packageName + "/"
8386                            + cpi.applicationInfo.uid + " for provider "
8387                            + name + ": user " + userId + " is stopped");
8388                    return null;
8389                }
8390
8391                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8392                cpr = mProviderMap.getProviderByClass(comp, userId);
8393                final boolean firstClass = cpr == null;
8394                if (firstClass) {
8395                    try {
8396                        ApplicationInfo ai =
8397                            AppGlobals.getPackageManager().
8398                                getApplicationInfo(
8399                                        cpi.applicationInfo.packageName,
8400                                        STOCK_PM_FLAGS, userId);
8401                        if (ai == null) {
8402                            Slog.w(TAG, "No package info for content provider "
8403                                    + cpi.name);
8404                            return null;
8405                        }
8406                        ai = getAppInfoForUser(ai, userId);
8407                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8408                    } catch (RemoteException ex) {
8409                        // pm is in same process, this will never happen.
8410                    }
8411                }
8412
8413                if (r != null && cpr.canRunHere(r)) {
8414                    // If this is a multiprocess provider, then just return its
8415                    // info and allow the caller to instantiate it.  Only do
8416                    // this if the provider is the same user as the caller's
8417                    // process, or can run as root (so can be in any process).
8418                    return cpr.newHolder(null);
8419                }
8420
8421                if (DEBUG_PROVIDER) {
8422                    RuntimeException e = new RuntimeException("here");
8423                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8424                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8425                }
8426
8427                // This is single process, and our app is now connecting to it.
8428                // See if we are already in the process of launching this
8429                // provider.
8430                final int N = mLaunchingProviders.size();
8431                int i;
8432                for (i=0; i<N; i++) {
8433                    if (mLaunchingProviders.get(i) == cpr) {
8434                        break;
8435                    }
8436                }
8437
8438                // If the provider is not already being launched, then get it
8439                // started.
8440                if (i >= N) {
8441                    final long origId = Binder.clearCallingIdentity();
8442
8443                    try {
8444                        // Content provider is now in use, its package can't be stopped.
8445                        try {
8446                            AppGlobals.getPackageManager().setPackageStoppedState(
8447                                    cpr.appInfo.packageName, false, userId);
8448                        } catch (RemoteException e) {
8449                        } catch (IllegalArgumentException e) {
8450                            Slog.w(TAG, "Failed trying to unstop package "
8451                                    + cpr.appInfo.packageName + ": " + e);
8452                        }
8453
8454                        // Use existing process if already started
8455                        ProcessRecord proc = getProcessRecordLocked(
8456                                cpi.processName, cpr.appInfo.uid, false);
8457                        if (proc != null && proc.thread != null) {
8458                            if (DEBUG_PROVIDER) {
8459                                Slog.d(TAG, "Installing in existing process " + proc);
8460                            }
8461                            proc.pubProviders.put(cpi.name, cpr);
8462                            try {
8463                                proc.thread.scheduleInstallProvider(cpi);
8464                            } catch (RemoteException e) {
8465                            }
8466                        } else {
8467                            proc = startProcessLocked(cpi.processName,
8468                                    cpr.appInfo, false, 0, "content provider",
8469                                    new ComponentName(cpi.applicationInfo.packageName,
8470                                            cpi.name), false, false, false);
8471                            if (proc == null) {
8472                                Slog.w(TAG, "Unable to launch app "
8473                                        + cpi.applicationInfo.packageName + "/"
8474                                        + cpi.applicationInfo.uid + " for provider "
8475                                        + name + ": process is bad");
8476                                return null;
8477                            }
8478                        }
8479                        cpr.launchingApp = proc;
8480                        mLaunchingProviders.add(cpr);
8481                    } finally {
8482                        Binder.restoreCallingIdentity(origId);
8483                    }
8484                }
8485
8486                // Make sure the provider is published (the same provider class
8487                // may be published under multiple names).
8488                if (firstClass) {
8489                    mProviderMap.putProviderByClass(comp, cpr);
8490                }
8491
8492                mProviderMap.putProviderByName(name, cpr);
8493                conn = incProviderCountLocked(r, cpr, token, stable);
8494                if (conn != null) {
8495                    conn.waiting = true;
8496                }
8497            }
8498        }
8499
8500        // Wait for the provider to be published...
8501        synchronized (cpr) {
8502            while (cpr.provider == null) {
8503                if (cpr.launchingApp == null) {
8504                    Slog.w(TAG, "Unable to launch app "
8505                            + cpi.applicationInfo.packageName + "/"
8506                            + cpi.applicationInfo.uid + " for provider "
8507                            + name + ": launching app became null");
8508                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8509                            UserHandle.getUserId(cpi.applicationInfo.uid),
8510                            cpi.applicationInfo.packageName,
8511                            cpi.applicationInfo.uid, name);
8512                    return null;
8513                }
8514                try {
8515                    if (DEBUG_MU) {
8516                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8517                                + cpr.launchingApp);
8518                    }
8519                    if (conn != null) {
8520                        conn.waiting = true;
8521                    }
8522                    cpr.wait();
8523                } catch (InterruptedException ex) {
8524                } finally {
8525                    if (conn != null) {
8526                        conn.waiting = false;
8527                    }
8528                }
8529            }
8530        }
8531        return cpr != null ? cpr.newHolder(conn) : null;
8532    }
8533
8534    @Override
8535    public final ContentProviderHolder getContentProvider(
8536            IApplicationThread caller, String name, int userId, boolean stable) {
8537        enforceNotIsolatedCaller("getContentProvider");
8538        if (caller == null) {
8539            String msg = "null IApplicationThread when getting content provider "
8540                    + name;
8541            Slog.w(TAG, msg);
8542            throw new SecurityException(msg);
8543        }
8544        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8545        // with cross-user grant.
8546        return getContentProviderImpl(caller, name, null, stable, userId);
8547    }
8548
8549    public ContentProviderHolder getContentProviderExternal(
8550            String name, int userId, IBinder token) {
8551        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8552            "Do not have permission in call getContentProviderExternal()");
8553        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8554                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8555        return getContentProviderExternalUnchecked(name, token, userId);
8556    }
8557
8558    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8559            IBinder token, int userId) {
8560        return getContentProviderImpl(null, name, token, true, userId);
8561    }
8562
8563    /**
8564     * Drop a content provider from a ProcessRecord's bookkeeping
8565     */
8566    public void removeContentProvider(IBinder connection, boolean stable) {
8567        enforceNotIsolatedCaller("removeContentProvider");
8568        long ident = Binder.clearCallingIdentity();
8569        try {
8570            synchronized (this) {
8571                ContentProviderConnection conn;
8572                try {
8573                    conn = (ContentProviderConnection)connection;
8574                } catch (ClassCastException e) {
8575                    String msg ="removeContentProvider: " + connection
8576                            + " not a ContentProviderConnection";
8577                    Slog.w(TAG, msg);
8578                    throw new IllegalArgumentException(msg);
8579                }
8580                if (conn == null) {
8581                    throw new NullPointerException("connection is null");
8582                }
8583                if (decProviderCountLocked(conn, null, null, stable)) {
8584                    updateOomAdjLocked();
8585                }
8586            }
8587        } finally {
8588            Binder.restoreCallingIdentity(ident);
8589        }
8590    }
8591
8592    public void removeContentProviderExternal(String name, IBinder token) {
8593        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8594            "Do not have permission in call removeContentProviderExternal()");
8595        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8596    }
8597
8598    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8599        synchronized (this) {
8600            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8601            if(cpr == null) {
8602                //remove from mProvidersByClass
8603                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8604                return;
8605            }
8606
8607            //update content provider record entry info
8608            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8609            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8610            if (localCpr.hasExternalProcessHandles()) {
8611                if (localCpr.removeExternalProcessHandleLocked(token)) {
8612                    updateOomAdjLocked();
8613                } else {
8614                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8615                            + " with no external reference for token: "
8616                            + token + ".");
8617                }
8618            } else {
8619                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8620                        + " with no external references.");
8621            }
8622        }
8623    }
8624
8625    public final void publishContentProviders(IApplicationThread caller,
8626            List<ContentProviderHolder> providers) {
8627        if (providers == null) {
8628            return;
8629        }
8630
8631        enforceNotIsolatedCaller("publishContentProviders");
8632        synchronized (this) {
8633            final ProcessRecord r = getRecordForAppLocked(caller);
8634            if (DEBUG_MU)
8635                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8636            if (r == null) {
8637                throw new SecurityException(
8638                        "Unable to find app for caller " + caller
8639                      + " (pid=" + Binder.getCallingPid()
8640                      + ") when publishing content providers");
8641            }
8642
8643            final long origId = Binder.clearCallingIdentity();
8644
8645            final int N = providers.size();
8646            for (int i=0; i<N; i++) {
8647                ContentProviderHolder src = providers.get(i);
8648                if (src == null || src.info == null || src.provider == null) {
8649                    continue;
8650                }
8651                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8652                if (DEBUG_MU)
8653                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8654                if (dst != null) {
8655                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8656                    mProviderMap.putProviderByClass(comp, dst);
8657                    String names[] = dst.info.authority.split(";");
8658                    for (int j = 0; j < names.length; j++) {
8659                        mProviderMap.putProviderByName(names[j], dst);
8660                    }
8661
8662                    int NL = mLaunchingProviders.size();
8663                    int j;
8664                    for (j=0; j<NL; j++) {
8665                        if (mLaunchingProviders.get(j) == dst) {
8666                            mLaunchingProviders.remove(j);
8667                            j--;
8668                            NL--;
8669                        }
8670                    }
8671                    synchronized (dst) {
8672                        dst.provider = src.provider;
8673                        dst.proc = r;
8674                        dst.notifyAll();
8675                    }
8676                    updateOomAdjLocked(r);
8677                }
8678            }
8679
8680            Binder.restoreCallingIdentity(origId);
8681        }
8682    }
8683
8684    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8685        ContentProviderConnection conn;
8686        try {
8687            conn = (ContentProviderConnection)connection;
8688        } catch (ClassCastException e) {
8689            String msg ="refContentProvider: " + connection
8690                    + " not a ContentProviderConnection";
8691            Slog.w(TAG, msg);
8692            throw new IllegalArgumentException(msg);
8693        }
8694        if (conn == null) {
8695            throw new NullPointerException("connection is null");
8696        }
8697
8698        synchronized (this) {
8699            if (stable > 0) {
8700                conn.numStableIncs += stable;
8701            }
8702            stable = conn.stableCount + stable;
8703            if (stable < 0) {
8704                throw new IllegalStateException("stableCount < 0: " + stable);
8705            }
8706
8707            if (unstable > 0) {
8708                conn.numUnstableIncs += unstable;
8709            }
8710            unstable = conn.unstableCount + unstable;
8711            if (unstable < 0) {
8712                throw new IllegalStateException("unstableCount < 0: " + unstable);
8713            }
8714
8715            if ((stable+unstable) <= 0) {
8716                throw new IllegalStateException("ref counts can't go to zero here: stable="
8717                        + stable + " unstable=" + unstable);
8718            }
8719            conn.stableCount = stable;
8720            conn.unstableCount = unstable;
8721            return !conn.dead;
8722        }
8723    }
8724
8725    public void unstableProviderDied(IBinder connection) {
8726        ContentProviderConnection conn;
8727        try {
8728            conn = (ContentProviderConnection)connection;
8729        } catch (ClassCastException e) {
8730            String msg ="refContentProvider: " + connection
8731                    + " not a ContentProviderConnection";
8732            Slog.w(TAG, msg);
8733            throw new IllegalArgumentException(msg);
8734        }
8735        if (conn == null) {
8736            throw new NullPointerException("connection is null");
8737        }
8738
8739        // Safely retrieve the content provider associated with the connection.
8740        IContentProvider provider;
8741        synchronized (this) {
8742            provider = conn.provider.provider;
8743        }
8744
8745        if (provider == null) {
8746            // Um, yeah, we're way ahead of you.
8747            return;
8748        }
8749
8750        // Make sure the caller is being honest with us.
8751        if (provider.asBinder().pingBinder()) {
8752            // Er, no, still looks good to us.
8753            synchronized (this) {
8754                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8755                        + " says " + conn + " died, but we don't agree");
8756                return;
8757            }
8758        }
8759
8760        // Well look at that!  It's dead!
8761        synchronized (this) {
8762            if (conn.provider.provider != provider) {
8763                // But something changed...  good enough.
8764                return;
8765            }
8766
8767            ProcessRecord proc = conn.provider.proc;
8768            if (proc == null || proc.thread == null) {
8769                // Seems like the process is already cleaned up.
8770                return;
8771            }
8772
8773            // As far as we're concerned, this is just like receiving a
8774            // death notification...  just a bit prematurely.
8775            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8776                    + ") early provider death");
8777            final long ident = Binder.clearCallingIdentity();
8778            try {
8779                appDiedLocked(proc, proc.pid, proc.thread);
8780            } finally {
8781                Binder.restoreCallingIdentity(ident);
8782            }
8783        }
8784    }
8785
8786    @Override
8787    public void appNotRespondingViaProvider(IBinder connection) {
8788        enforceCallingPermission(
8789                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8790
8791        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8792        if (conn == null) {
8793            Slog.w(TAG, "ContentProviderConnection is null");
8794            return;
8795        }
8796
8797        final ProcessRecord host = conn.provider.proc;
8798        if (host == null) {
8799            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8800            return;
8801        }
8802
8803        final long token = Binder.clearCallingIdentity();
8804        try {
8805            appNotResponding(host, null, null, false, "ContentProvider not responding");
8806        } finally {
8807            Binder.restoreCallingIdentity(token);
8808        }
8809    }
8810
8811    public final void installSystemProviders() {
8812        List<ProviderInfo> providers;
8813        synchronized (this) {
8814            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8815            providers = generateApplicationProvidersLocked(app);
8816            if (providers != null) {
8817                for (int i=providers.size()-1; i>=0; i--) {
8818                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8819                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8820                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8821                                + ": not system .apk");
8822                        providers.remove(i);
8823                    }
8824                }
8825            }
8826        }
8827        if (providers != null) {
8828            mSystemThread.installSystemProviders(providers);
8829        }
8830
8831        mCoreSettingsObserver = new CoreSettingsObserver(this);
8832
8833        //mUsageStatsService.monitorPackages();
8834    }
8835
8836    /**
8837     * Allows app to retrieve the MIME type of a URI without having permission
8838     * to access its content provider.
8839     *
8840     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8841     *
8842     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8843     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8844     */
8845    public String getProviderMimeType(Uri uri, int userId) {
8846        enforceNotIsolatedCaller("getProviderMimeType");
8847        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8848                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8849        final String name = uri.getAuthority();
8850        final long ident = Binder.clearCallingIdentity();
8851        ContentProviderHolder holder = null;
8852
8853        try {
8854            holder = getContentProviderExternalUnchecked(name, null, userId);
8855            if (holder != null) {
8856                return holder.provider.getType(uri);
8857            }
8858        } catch (RemoteException e) {
8859            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8860            return null;
8861        } finally {
8862            if (holder != null) {
8863                removeContentProviderExternalUnchecked(name, null, userId);
8864            }
8865            Binder.restoreCallingIdentity(ident);
8866        }
8867
8868        return null;
8869    }
8870
8871    // =========================================================
8872    // GLOBAL MANAGEMENT
8873    // =========================================================
8874
8875    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8876            boolean isolated) {
8877        String proc = customProcess != null ? customProcess : info.processName;
8878        BatteryStatsImpl.Uid.Proc ps = null;
8879        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8880        int uid = info.uid;
8881        if (isolated) {
8882            int userId = UserHandle.getUserId(uid);
8883            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8884            while (true) {
8885                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8886                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8887                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8888                }
8889                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8890                mNextIsolatedProcessUid++;
8891                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8892                    // No process for this uid, use it.
8893                    break;
8894                }
8895                stepsLeft--;
8896                if (stepsLeft <= 0) {
8897                    return null;
8898                }
8899            }
8900        }
8901        return new ProcessRecord(stats, info, proc, uid);
8902    }
8903
8904    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8905            String abiOverride) {
8906        ProcessRecord app;
8907        if (!isolated) {
8908            app = getProcessRecordLocked(info.processName, info.uid, true);
8909        } else {
8910            app = null;
8911        }
8912
8913        if (app == null) {
8914            app = newProcessRecordLocked(info, null, isolated);
8915            mProcessNames.put(info.processName, app.uid, app);
8916            if (isolated) {
8917                mIsolatedProcesses.put(app.uid, app);
8918            }
8919            updateLruProcessLocked(app, false, null);
8920            updateOomAdjLocked();
8921        }
8922
8923        // This package really, really can not be stopped.
8924        try {
8925            AppGlobals.getPackageManager().setPackageStoppedState(
8926                    info.packageName, false, UserHandle.getUserId(app.uid));
8927        } catch (RemoteException e) {
8928        } catch (IllegalArgumentException e) {
8929            Slog.w(TAG, "Failed trying to unstop package "
8930                    + info.packageName + ": " + e);
8931        }
8932
8933        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8934                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8935            app.persistent = true;
8936            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8937        }
8938        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8939            mPersistentStartingProcesses.add(app);
8940            startProcessLocked(app, "added application", app.processName,
8941                    abiOverride);
8942        }
8943
8944        return app;
8945    }
8946
8947    public void unhandledBack() {
8948        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8949                "unhandledBack()");
8950
8951        synchronized(this) {
8952            final long origId = Binder.clearCallingIdentity();
8953            try {
8954                getFocusedStack().unhandledBackLocked();
8955            } finally {
8956                Binder.restoreCallingIdentity(origId);
8957            }
8958        }
8959    }
8960
8961    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8962        enforceNotIsolatedCaller("openContentUri");
8963        final int userId = UserHandle.getCallingUserId();
8964        String name = uri.getAuthority();
8965        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8966        ParcelFileDescriptor pfd = null;
8967        if (cph != null) {
8968            // We record the binder invoker's uid in thread-local storage before
8969            // going to the content provider to open the file.  Later, in the code
8970            // that handles all permissions checks, we look for this uid and use
8971            // that rather than the Activity Manager's own uid.  The effect is that
8972            // we do the check against the caller's permissions even though it looks
8973            // to the content provider like the Activity Manager itself is making
8974            // the request.
8975            sCallerIdentity.set(new Identity(
8976                    Binder.getCallingPid(), Binder.getCallingUid()));
8977            try {
8978                pfd = cph.provider.openFile(null, uri, "r", null);
8979            } catch (FileNotFoundException e) {
8980                // do nothing; pfd will be returned null
8981            } finally {
8982                // Ensure that whatever happens, we clean up the identity state
8983                sCallerIdentity.remove();
8984            }
8985
8986            // We've got the fd now, so we're done with the provider.
8987            removeContentProviderExternalUnchecked(name, null, userId);
8988        } else {
8989            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8990        }
8991        return pfd;
8992    }
8993
8994    // Actually is sleeping or shutting down or whatever else in the future
8995    // is an inactive state.
8996    public boolean isSleepingOrShuttingDown() {
8997        return mSleeping || mShuttingDown;
8998    }
8999
9000    public boolean isSleeping() {
9001        return mSleeping;
9002    }
9003
9004    void goingToSleep() {
9005        synchronized(this) {
9006            mWentToSleep = true;
9007            updateEventDispatchingLocked();
9008            goToSleepIfNeededLocked();
9009        }
9010    }
9011
9012    void finishRunningVoiceLocked() {
9013        if (mRunningVoice) {
9014            mRunningVoice = false;
9015            goToSleepIfNeededLocked();
9016        }
9017    }
9018
9019    void goToSleepIfNeededLocked() {
9020        if (mWentToSleep && !mRunningVoice) {
9021            if (!mSleeping) {
9022                mSleeping = true;
9023                mStackSupervisor.goingToSleepLocked();
9024
9025                // Initialize the wake times of all processes.
9026                checkExcessivePowerUsageLocked(false);
9027                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9028                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9029                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9030            }
9031        }
9032    }
9033
9034    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9035        mTaskPersister.notify(task, flush);
9036    }
9037
9038    @Override
9039    public boolean shutdown(int timeout) {
9040        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9041                != PackageManager.PERMISSION_GRANTED) {
9042            throw new SecurityException("Requires permission "
9043                    + android.Manifest.permission.SHUTDOWN);
9044        }
9045
9046        boolean timedout = false;
9047
9048        synchronized(this) {
9049            mShuttingDown = true;
9050            updateEventDispatchingLocked();
9051            timedout = mStackSupervisor.shutdownLocked(timeout);
9052        }
9053
9054        mAppOpsService.shutdown();
9055        if (mUsageStatsService != null) {
9056            mUsageStatsService.prepareShutdown();
9057        }
9058        mBatteryStatsService.shutdown();
9059        synchronized (this) {
9060            mProcessStats.shutdownLocked();
9061        }
9062        notifyTaskPersisterLocked(null, true);
9063
9064        return timedout;
9065    }
9066
9067    public final void activitySlept(IBinder token) {
9068        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9069
9070        final long origId = Binder.clearCallingIdentity();
9071
9072        synchronized (this) {
9073            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9074            if (r != null) {
9075                mStackSupervisor.activitySleptLocked(r);
9076            }
9077        }
9078
9079        Binder.restoreCallingIdentity(origId);
9080    }
9081
9082    void logLockScreen(String msg) {
9083        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9084                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9085                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9086                mStackSupervisor.mDismissKeyguardOnNextActivity);
9087    }
9088
9089    private void comeOutOfSleepIfNeededLocked() {
9090        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9091            if (mSleeping) {
9092                mSleeping = false;
9093                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9094            }
9095        }
9096    }
9097
9098    void wakingUp() {
9099        synchronized(this) {
9100            mWentToSleep = false;
9101            updateEventDispatchingLocked();
9102            comeOutOfSleepIfNeededLocked();
9103        }
9104    }
9105
9106    void startRunningVoiceLocked() {
9107        if (!mRunningVoice) {
9108            mRunningVoice = true;
9109            comeOutOfSleepIfNeededLocked();
9110        }
9111    }
9112
9113    private void updateEventDispatchingLocked() {
9114        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9115    }
9116
9117    public void setLockScreenShown(boolean shown) {
9118        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9119                != PackageManager.PERMISSION_GRANTED) {
9120            throw new SecurityException("Requires permission "
9121                    + android.Manifest.permission.DEVICE_POWER);
9122        }
9123
9124        synchronized(this) {
9125            long ident = Binder.clearCallingIdentity();
9126            try {
9127                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9128                mLockScreenShown = shown;
9129                comeOutOfSleepIfNeededLocked();
9130            } finally {
9131                Binder.restoreCallingIdentity(ident);
9132            }
9133        }
9134    }
9135
9136    @Override
9137    public void stopAppSwitches() {
9138        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9139                != PackageManager.PERMISSION_GRANTED) {
9140            throw new SecurityException("Requires permission "
9141                    + android.Manifest.permission.STOP_APP_SWITCHES);
9142        }
9143
9144        synchronized(this) {
9145            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9146                    + APP_SWITCH_DELAY_TIME;
9147            mDidAppSwitch = false;
9148            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9149            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9150            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9151        }
9152    }
9153
9154    public void resumeAppSwitches() {
9155        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9156                != PackageManager.PERMISSION_GRANTED) {
9157            throw new SecurityException("Requires permission "
9158                    + android.Manifest.permission.STOP_APP_SWITCHES);
9159        }
9160
9161        synchronized(this) {
9162            // Note that we don't execute any pending app switches... we will
9163            // let those wait until either the timeout, or the next start
9164            // activity request.
9165            mAppSwitchesAllowedTime = 0;
9166        }
9167    }
9168
9169    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9170            String name) {
9171        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9172            return true;
9173        }
9174
9175        final int perm = checkComponentPermission(
9176                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9177                callingUid, -1, true);
9178        if (perm == PackageManager.PERMISSION_GRANTED) {
9179            return true;
9180        }
9181
9182        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9183        return false;
9184    }
9185
9186    public void setDebugApp(String packageName, boolean waitForDebugger,
9187            boolean persistent) {
9188        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9189                "setDebugApp()");
9190
9191        long ident = Binder.clearCallingIdentity();
9192        try {
9193            // Note that this is not really thread safe if there are multiple
9194            // callers into it at the same time, but that's not a situation we
9195            // care about.
9196            if (persistent) {
9197                final ContentResolver resolver = mContext.getContentResolver();
9198                Settings.Global.putString(
9199                    resolver, Settings.Global.DEBUG_APP,
9200                    packageName);
9201                Settings.Global.putInt(
9202                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9203                    waitForDebugger ? 1 : 0);
9204            }
9205
9206            synchronized (this) {
9207                if (!persistent) {
9208                    mOrigDebugApp = mDebugApp;
9209                    mOrigWaitForDebugger = mWaitForDebugger;
9210                }
9211                mDebugApp = packageName;
9212                mWaitForDebugger = waitForDebugger;
9213                mDebugTransient = !persistent;
9214                if (packageName != null) {
9215                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9216                            false, UserHandle.USER_ALL, "set debug app");
9217                }
9218            }
9219        } finally {
9220            Binder.restoreCallingIdentity(ident);
9221        }
9222    }
9223
9224    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9225        synchronized (this) {
9226            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9227            if (!isDebuggable) {
9228                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9229                    throw new SecurityException("Process not debuggable: " + app.packageName);
9230                }
9231            }
9232
9233            mOpenGlTraceApp = processName;
9234        }
9235    }
9236
9237    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9238            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9239        synchronized (this) {
9240            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9241            if (!isDebuggable) {
9242                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9243                    throw new SecurityException("Process not debuggable: " + app.packageName);
9244                }
9245            }
9246            mProfileApp = processName;
9247            mProfileFile = profileFile;
9248            if (mProfileFd != null) {
9249                try {
9250                    mProfileFd.close();
9251                } catch (IOException e) {
9252                }
9253                mProfileFd = null;
9254            }
9255            mProfileFd = profileFd;
9256            mProfileType = 0;
9257            mAutoStopProfiler = autoStopProfiler;
9258        }
9259    }
9260
9261    @Override
9262    public void setAlwaysFinish(boolean enabled) {
9263        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9264                "setAlwaysFinish()");
9265
9266        Settings.Global.putInt(
9267                mContext.getContentResolver(),
9268                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9269
9270        synchronized (this) {
9271            mAlwaysFinishActivities = enabled;
9272        }
9273    }
9274
9275    @Override
9276    public void setActivityController(IActivityController controller) {
9277        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9278                "setActivityController()");
9279        synchronized (this) {
9280            mController = controller;
9281            Watchdog.getInstance().setActivityController(controller);
9282        }
9283    }
9284
9285    @Override
9286    public void setUserIsMonkey(boolean userIsMonkey) {
9287        synchronized (this) {
9288            synchronized (mPidsSelfLocked) {
9289                final int callingPid = Binder.getCallingPid();
9290                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9291                if (precessRecord == null) {
9292                    throw new SecurityException("Unknown process: " + callingPid);
9293                }
9294                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9295                    throw new SecurityException("Only an instrumentation process "
9296                            + "with a UiAutomation can call setUserIsMonkey");
9297                }
9298            }
9299            mUserIsMonkey = userIsMonkey;
9300        }
9301    }
9302
9303    @Override
9304    public boolean isUserAMonkey() {
9305        synchronized (this) {
9306            // If there is a controller also implies the user is a monkey.
9307            return (mUserIsMonkey || mController != null);
9308        }
9309    }
9310
9311    public void requestBugReport() {
9312        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9313        SystemProperties.set("ctl.start", "bugreport");
9314    }
9315
9316    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9317        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9318    }
9319
9320    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9321        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9322            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9323        }
9324        return KEY_DISPATCHING_TIMEOUT;
9325    }
9326
9327    @Override
9328    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9329        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9330                != PackageManager.PERMISSION_GRANTED) {
9331            throw new SecurityException("Requires permission "
9332                    + android.Manifest.permission.FILTER_EVENTS);
9333        }
9334        ProcessRecord proc;
9335        long timeout;
9336        synchronized (this) {
9337            synchronized (mPidsSelfLocked) {
9338                proc = mPidsSelfLocked.get(pid);
9339            }
9340            timeout = getInputDispatchingTimeoutLocked(proc);
9341        }
9342
9343        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9344            return -1;
9345        }
9346
9347        return timeout;
9348    }
9349
9350    /**
9351     * Handle input dispatching timeouts.
9352     * Returns whether input dispatching should be aborted or not.
9353     */
9354    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9355            final ActivityRecord activity, final ActivityRecord parent,
9356            final boolean aboveSystem, String reason) {
9357        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9358                != PackageManager.PERMISSION_GRANTED) {
9359            throw new SecurityException("Requires permission "
9360                    + android.Manifest.permission.FILTER_EVENTS);
9361        }
9362
9363        final String annotation;
9364        if (reason == null) {
9365            annotation = "Input dispatching timed out";
9366        } else {
9367            annotation = "Input dispatching timed out (" + reason + ")";
9368        }
9369
9370        if (proc != null) {
9371            synchronized (this) {
9372                if (proc.debugging) {
9373                    return false;
9374                }
9375
9376                if (mDidDexOpt) {
9377                    // Give more time since we were dexopting.
9378                    mDidDexOpt = false;
9379                    return false;
9380                }
9381
9382                if (proc.instrumentationClass != null) {
9383                    Bundle info = new Bundle();
9384                    info.putString("shortMsg", "keyDispatchingTimedOut");
9385                    info.putString("longMsg", annotation);
9386                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9387                    return true;
9388                }
9389            }
9390            mHandler.post(new Runnable() {
9391                @Override
9392                public void run() {
9393                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9394                }
9395            });
9396        }
9397
9398        return true;
9399    }
9400
9401    public Bundle getAssistContextExtras(int requestType) {
9402        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9403                "getAssistContextExtras()");
9404        PendingAssistExtras pae;
9405        Bundle extras = new Bundle();
9406        synchronized (this) {
9407            ActivityRecord activity = getFocusedStack().mResumedActivity;
9408            if (activity == null) {
9409                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9410                return null;
9411            }
9412            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9413            if (activity.app == null || activity.app.thread == null) {
9414                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9415                return extras;
9416            }
9417            if (activity.app.pid == Binder.getCallingPid()) {
9418                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9419                return extras;
9420            }
9421            pae = new PendingAssistExtras(activity);
9422            try {
9423                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9424                        requestType);
9425                mPendingAssistExtras.add(pae);
9426                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9427            } catch (RemoteException e) {
9428                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9429                return extras;
9430            }
9431        }
9432        synchronized (pae) {
9433            while (!pae.haveResult) {
9434                try {
9435                    pae.wait();
9436                } catch (InterruptedException e) {
9437                }
9438            }
9439            if (pae.result != null) {
9440                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9441            }
9442        }
9443        synchronized (this) {
9444            mPendingAssistExtras.remove(pae);
9445            mHandler.removeCallbacks(pae);
9446        }
9447        return extras;
9448    }
9449
9450    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9451        PendingAssistExtras pae = (PendingAssistExtras)token;
9452        synchronized (pae) {
9453            pae.result = extras;
9454            pae.haveResult = true;
9455            pae.notifyAll();
9456        }
9457    }
9458
9459    public void registerProcessObserver(IProcessObserver observer) {
9460        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9461                "registerProcessObserver()");
9462        synchronized (this) {
9463            mProcessObservers.register(observer);
9464        }
9465    }
9466
9467    @Override
9468    public void unregisterProcessObserver(IProcessObserver observer) {
9469        synchronized (this) {
9470            mProcessObservers.unregister(observer);
9471        }
9472    }
9473
9474    @Override
9475    public boolean convertFromTranslucent(IBinder token) {
9476        final long origId = Binder.clearCallingIdentity();
9477        try {
9478            synchronized (this) {
9479                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9480                if (r == null) {
9481                    return false;
9482                }
9483                if (r.changeWindowTranslucency(true)) {
9484                    mWindowManager.setAppFullscreen(token, true);
9485                    r.task.stack.releaseMediaResources();
9486                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9487                    return true;
9488                }
9489                return false;
9490            }
9491        } finally {
9492            Binder.restoreCallingIdentity(origId);
9493        }
9494    }
9495
9496    @Override
9497    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9498        final long origId = Binder.clearCallingIdentity();
9499        try {
9500            synchronized (this) {
9501                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9502                if (r == null) {
9503                    return false;
9504                }
9505                if (r.changeWindowTranslucency(false)) {
9506                    r.task.stack.convertToTranslucent(r, options);
9507                    mWindowManager.setAppFullscreen(token, false);
9508                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9509                    return true;
9510                } else {
9511                    r.task.stack.mReturningActivityOptions = options;
9512                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9513                    return false;
9514                }
9515            }
9516        } finally {
9517            Binder.restoreCallingIdentity(origId);
9518        }
9519    }
9520
9521    @Override
9522    public boolean setMediaPlaying(IBinder token, boolean playing) {
9523        final long origId = Binder.clearCallingIdentity();
9524        try {
9525            synchronized (this) {
9526                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9527                if (r != null) {
9528                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9529                }
9530            }
9531            return false;
9532        } finally {
9533            Binder.restoreCallingIdentity(origId);
9534        }
9535    }
9536
9537    @Override
9538    public boolean isBackgroundMediaPlaying(IBinder token) {
9539        final long origId = Binder.clearCallingIdentity();
9540        try {
9541            synchronized (this) {
9542                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9543                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9544                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9545                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9546                return playing;
9547            }
9548        } finally {
9549            Binder.restoreCallingIdentity(origId);
9550        }
9551    }
9552
9553    @Override
9554    public ActivityOptions getActivityOptions(IBinder token) {
9555        final long origId = Binder.clearCallingIdentity();
9556        try {
9557            synchronized (this) {
9558                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9559                if (r != null) {
9560                    final ActivityOptions activityOptions = r.pendingOptions;
9561                    r.pendingOptions = null;
9562                    return activityOptions;
9563                }
9564                return null;
9565            }
9566        } finally {
9567            Binder.restoreCallingIdentity(origId);
9568        }
9569    }
9570
9571    @Override
9572    public void setImmersive(IBinder token, boolean immersive) {
9573        synchronized(this) {
9574            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9575            if (r == null) {
9576                throw new IllegalArgumentException();
9577            }
9578            r.immersive = immersive;
9579
9580            // update associated state if we're frontmost
9581            if (r == mFocusedActivity) {
9582                if (DEBUG_IMMERSIVE) {
9583                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9584                }
9585                applyUpdateLockStateLocked(r);
9586            }
9587        }
9588    }
9589
9590    @Override
9591    public boolean isImmersive(IBinder token) {
9592        synchronized (this) {
9593            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9594            if (r == null) {
9595                throw new IllegalArgumentException();
9596            }
9597            return r.immersive;
9598        }
9599    }
9600
9601    public boolean isTopActivityImmersive() {
9602        enforceNotIsolatedCaller("startActivity");
9603        synchronized (this) {
9604            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9605            return (r != null) ? r.immersive : false;
9606        }
9607    }
9608
9609    @Override
9610    public boolean isTopOfTask(IBinder token) {
9611        synchronized (this) {
9612            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9613            if (r == null) {
9614                throw new IllegalArgumentException();
9615            }
9616            return r.task.getTopActivity() == r;
9617        }
9618    }
9619
9620    public final void enterSafeMode() {
9621        synchronized(this) {
9622            // It only makes sense to do this before the system is ready
9623            // and started launching other packages.
9624            if (!mSystemReady) {
9625                try {
9626                    AppGlobals.getPackageManager().enterSafeMode();
9627                } catch (RemoteException e) {
9628                }
9629            }
9630
9631            mSafeMode = true;
9632        }
9633    }
9634
9635    public final void showSafeModeOverlay() {
9636        View v = LayoutInflater.from(mContext).inflate(
9637                com.android.internal.R.layout.safe_mode, null);
9638        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9639        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9640        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9641        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9642        lp.gravity = Gravity.BOTTOM | Gravity.START;
9643        lp.format = v.getBackground().getOpacity();
9644        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9645                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9646        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9647        ((WindowManager)mContext.getSystemService(
9648                Context.WINDOW_SERVICE)).addView(v, lp);
9649    }
9650
9651    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9652        if (!(sender instanceof PendingIntentRecord)) {
9653            return;
9654        }
9655        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9656        synchronized (stats) {
9657            if (mBatteryStatsService.isOnBattery()) {
9658                mBatteryStatsService.enforceCallingPermission();
9659                PendingIntentRecord rec = (PendingIntentRecord)sender;
9660                int MY_UID = Binder.getCallingUid();
9661                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9662                BatteryStatsImpl.Uid.Pkg pkg =
9663                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9664                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9665                pkg.incWakeupsLocked();
9666            }
9667        }
9668    }
9669
9670    public boolean killPids(int[] pids, String pReason, boolean secure) {
9671        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9672            throw new SecurityException("killPids only available to the system");
9673        }
9674        String reason = (pReason == null) ? "Unknown" : pReason;
9675        // XXX Note: don't acquire main activity lock here, because the window
9676        // manager calls in with its locks held.
9677
9678        boolean killed = false;
9679        synchronized (mPidsSelfLocked) {
9680            int[] types = new int[pids.length];
9681            int worstType = 0;
9682            for (int i=0; i<pids.length; i++) {
9683                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9684                if (proc != null) {
9685                    int type = proc.setAdj;
9686                    types[i] = type;
9687                    if (type > worstType) {
9688                        worstType = type;
9689                    }
9690                }
9691            }
9692
9693            // If the worst oom_adj is somewhere in the cached proc LRU range,
9694            // then constrain it so we will kill all cached procs.
9695            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9696                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9697                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9698            }
9699
9700            // If this is not a secure call, don't let it kill processes that
9701            // are important.
9702            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9703                worstType = ProcessList.SERVICE_ADJ;
9704            }
9705
9706            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9707            for (int i=0; i<pids.length; i++) {
9708                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9709                if (proc == null) {
9710                    continue;
9711                }
9712                int adj = proc.setAdj;
9713                if (adj >= worstType && !proc.killedByAm) {
9714                    killUnneededProcessLocked(proc, reason);
9715                    killed = true;
9716                }
9717            }
9718        }
9719        return killed;
9720    }
9721
9722    @Override
9723    public void killUid(int uid, String reason) {
9724        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9725            throw new SecurityException("killUid only available to the system");
9726        }
9727        synchronized (this) {
9728            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9729                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9730                    reason != null ? reason : "kill uid");
9731        }
9732    }
9733
9734    @Override
9735    public boolean killProcessesBelowForeground(String reason) {
9736        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9737            throw new SecurityException("killProcessesBelowForeground() only available to system");
9738        }
9739
9740        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9741    }
9742
9743    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9744        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9745            throw new SecurityException("killProcessesBelowAdj() only available to system");
9746        }
9747
9748        boolean killed = false;
9749        synchronized (mPidsSelfLocked) {
9750            final int size = mPidsSelfLocked.size();
9751            for (int i = 0; i < size; i++) {
9752                final int pid = mPidsSelfLocked.keyAt(i);
9753                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9754                if (proc == null) continue;
9755
9756                final int adj = proc.setAdj;
9757                if (adj > belowAdj && !proc.killedByAm) {
9758                    killUnneededProcessLocked(proc, reason);
9759                    killed = true;
9760                }
9761            }
9762        }
9763        return killed;
9764    }
9765
9766    @Override
9767    public void hang(final IBinder who, boolean allowRestart) {
9768        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9769                != PackageManager.PERMISSION_GRANTED) {
9770            throw new SecurityException("Requires permission "
9771                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9772        }
9773
9774        final IBinder.DeathRecipient death = new DeathRecipient() {
9775            @Override
9776            public void binderDied() {
9777                synchronized (this) {
9778                    notifyAll();
9779                }
9780            }
9781        };
9782
9783        try {
9784            who.linkToDeath(death, 0);
9785        } catch (RemoteException e) {
9786            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9787            return;
9788        }
9789
9790        synchronized (this) {
9791            Watchdog.getInstance().setAllowRestart(allowRestart);
9792            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9793            synchronized (death) {
9794                while (who.isBinderAlive()) {
9795                    try {
9796                        death.wait();
9797                    } catch (InterruptedException e) {
9798                    }
9799                }
9800            }
9801            Watchdog.getInstance().setAllowRestart(true);
9802        }
9803    }
9804
9805    @Override
9806    public void restart() {
9807        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9808                != PackageManager.PERMISSION_GRANTED) {
9809            throw new SecurityException("Requires permission "
9810                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9811        }
9812
9813        Log.i(TAG, "Sending shutdown broadcast...");
9814
9815        BroadcastReceiver br = new BroadcastReceiver() {
9816            @Override public void onReceive(Context context, Intent intent) {
9817                // Now the broadcast is done, finish up the low-level shutdown.
9818                Log.i(TAG, "Shutting down activity manager...");
9819                shutdown(10000);
9820                Log.i(TAG, "Shutdown complete, restarting!");
9821                Process.killProcess(Process.myPid());
9822                System.exit(10);
9823            }
9824        };
9825
9826        // First send the high-level shut down broadcast.
9827        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9828        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9829        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9830        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9831        mContext.sendOrderedBroadcastAsUser(intent,
9832                UserHandle.ALL, null, br, mHandler, 0, null, null);
9833        */
9834        br.onReceive(mContext, intent);
9835    }
9836
9837    private long getLowRamTimeSinceIdle(long now) {
9838        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9839    }
9840
9841    @Override
9842    public void performIdleMaintenance() {
9843        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9844                != PackageManager.PERMISSION_GRANTED) {
9845            throw new SecurityException("Requires permission "
9846                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9847        }
9848
9849        synchronized (this) {
9850            final long now = SystemClock.uptimeMillis();
9851            final long timeSinceLastIdle = now - mLastIdleTime;
9852            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9853            mLastIdleTime = now;
9854            mLowRamTimeSinceLastIdle = 0;
9855            if (mLowRamStartTime != 0) {
9856                mLowRamStartTime = now;
9857            }
9858
9859            StringBuilder sb = new StringBuilder(128);
9860            sb.append("Idle maintenance over ");
9861            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9862            sb.append(" low RAM for ");
9863            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9864            Slog.i(TAG, sb.toString());
9865
9866            // If at least 1/3 of our time since the last idle period has been spent
9867            // with RAM low, then we want to kill processes.
9868            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9869
9870            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9871                ProcessRecord proc = mLruProcesses.get(i);
9872                if (proc.notCachedSinceIdle) {
9873                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9874                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9875                        if (doKilling && proc.initialIdlePss != 0
9876                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9877                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9878                                    + " from " + proc.initialIdlePss + ")");
9879                        }
9880                    }
9881                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9882                    proc.notCachedSinceIdle = true;
9883                    proc.initialIdlePss = 0;
9884                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9885                            isSleeping(), now);
9886                }
9887            }
9888
9889            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9890            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9891        }
9892    }
9893
9894    private void retrieveSettings() {
9895        final ContentResolver resolver = mContext.getContentResolver();
9896        String debugApp = Settings.Global.getString(
9897            resolver, Settings.Global.DEBUG_APP);
9898        boolean waitForDebugger = Settings.Global.getInt(
9899            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9900        boolean alwaysFinishActivities = Settings.Global.getInt(
9901            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9902        boolean forceRtl = Settings.Global.getInt(
9903                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9904        // Transfer any global setting for forcing RTL layout, into a System Property
9905        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9906
9907        Configuration configuration = new Configuration();
9908        Settings.System.getConfiguration(resolver, configuration);
9909        if (forceRtl) {
9910            // This will take care of setting the correct layout direction flags
9911            configuration.setLayoutDirection(configuration.locale);
9912        }
9913
9914        synchronized (this) {
9915            mDebugApp = mOrigDebugApp = debugApp;
9916            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9917            mAlwaysFinishActivities = alwaysFinishActivities;
9918            // This happens before any activities are started, so we can
9919            // change mConfiguration in-place.
9920            updateConfigurationLocked(configuration, null, false, true);
9921            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9922        }
9923    }
9924
9925    public boolean testIsSystemReady() {
9926        // no need to synchronize(this) just to read & return the value
9927        return mSystemReady;
9928    }
9929
9930    private static File getCalledPreBootReceiversFile() {
9931        File dataDir = Environment.getDataDirectory();
9932        File systemDir = new File(dataDir, "system");
9933        File fname = new File(systemDir, "called_pre_boots.dat");
9934        return fname;
9935    }
9936
9937    static final int LAST_DONE_VERSION = 10000;
9938
9939    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9940        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9941        File file = getCalledPreBootReceiversFile();
9942        FileInputStream fis = null;
9943        try {
9944            fis = new FileInputStream(file);
9945            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9946            int fvers = dis.readInt();
9947            if (fvers == LAST_DONE_VERSION) {
9948                String vers = dis.readUTF();
9949                String codename = dis.readUTF();
9950                String build = dis.readUTF();
9951                if (android.os.Build.VERSION.RELEASE.equals(vers)
9952                        && android.os.Build.VERSION.CODENAME.equals(codename)
9953                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9954                    int num = dis.readInt();
9955                    while (num > 0) {
9956                        num--;
9957                        String pkg = dis.readUTF();
9958                        String cls = dis.readUTF();
9959                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9960                    }
9961                }
9962            }
9963        } catch (FileNotFoundException e) {
9964        } catch (IOException e) {
9965            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9966        } finally {
9967            if (fis != null) {
9968                try {
9969                    fis.close();
9970                } catch (IOException e) {
9971                }
9972            }
9973        }
9974        return lastDoneReceivers;
9975    }
9976
9977    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9978        File file = getCalledPreBootReceiversFile();
9979        FileOutputStream fos = null;
9980        DataOutputStream dos = null;
9981        try {
9982            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9983            fos = new FileOutputStream(file);
9984            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9985            dos.writeInt(LAST_DONE_VERSION);
9986            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9987            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9988            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9989            dos.writeInt(list.size());
9990            for (int i=0; i<list.size(); i++) {
9991                dos.writeUTF(list.get(i).getPackageName());
9992                dos.writeUTF(list.get(i).getClassName());
9993            }
9994        } catch (IOException e) {
9995            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9996            file.delete();
9997        } finally {
9998            FileUtils.sync(fos);
9999            if (dos != null) {
10000                try {
10001                    dos.close();
10002                } catch (IOException e) {
10003                    // TODO Auto-generated catch block
10004                    e.printStackTrace();
10005                }
10006            }
10007        }
10008    }
10009
10010    public void systemReady(final Runnable goingCallback) {
10011        synchronized(this) {
10012            if (mSystemReady) {
10013                if (goingCallback != null) goingCallback.run();
10014                return;
10015            }
10016
10017            // Make sure we have the current profile info, since it is needed for
10018            // security checks.
10019            updateCurrentProfileIdsLocked();
10020
10021            if (mRecentTasks == null) {
10022                mRecentTasks = mTaskPersister.restoreTasksLocked();
10023                if (!mRecentTasks.isEmpty()) {
10024                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10025                }
10026                mTaskPersister.startPersisting();
10027            }
10028
10029            // Check to see if there are any update receivers to run.
10030            if (!mDidUpdate) {
10031                if (mWaitingUpdate) {
10032                    return;
10033                }
10034                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10035                List<ResolveInfo> ris = null;
10036                try {
10037                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
10038                            intent, null, 0, 0);
10039                } catch (RemoteException e) {
10040                }
10041                if (ris != null) {
10042                    for (int i=ris.size()-1; i>=0; i--) {
10043                        if ((ris.get(i).activityInfo.applicationInfo.flags
10044                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
10045                            ris.remove(i);
10046                        }
10047                    }
10048                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10049
10050                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10051
10052                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10053                    for (int i=0; i<ris.size(); i++) {
10054                        ActivityInfo ai = ris.get(i).activityInfo;
10055                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10056                        if (lastDoneReceivers.contains(comp)) {
10057                            // We already did the pre boot receiver for this app with the current
10058                            // platform version, so don't do it again...
10059                            ris.remove(i);
10060                            i--;
10061                            // ...however, do keep it as one that has been done, so we don't
10062                            // forget about it when rewriting the file of last done receivers.
10063                            doneReceivers.add(comp);
10064                        }
10065                    }
10066
10067                    final int[] users = getUsersLocked();
10068                    for (int i=0; i<ris.size(); i++) {
10069                        ActivityInfo ai = ris.get(i).activityInfo;
10070                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10071                        doneReceivers.add(comp);
10072                        intent.setComponent(comp);
10073                        for (int j=0; j<users.length; j++) {
10074                            IIntentReceiver finisher = null;
10075                            if (i == ris.size()-1 && j == users.length-1) {
10076                                finisher = new IIntentReceiver.Stub() {
10077                                    public void performReceive(Intent intent, int resultCode,
10078                                            String data, Bundle extras, boolean ordered,
10079                                            boolean sticky, int sendingUser) {
10080                                        // The raw IIntentReceiver interface is called
10081                                        // with the AM lock held, so redispatch to
10082                                        // execute our code without the lock.
10083                                        mHandler.post(new Runnable() {
10084                                            public void run() {
10085                                                synchronized (ActivityManagerService.this) {
10086                                                    mDidUpdate = true;
10087                                                }
10088                                                writeLastDonePreBootReceivers(doneReceivers);
10089                                                showBootMessage(mContext.getText(
10090                                                        R.string.android_upgrading_complete),
10091                                                        false);
10092                                                systemReady(goingCallback);
10093                                            }
10094                                        });
10095                                    }
10096                                };
10097                            }
10098                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
10099                                    + " for user " + users[j]);
10100                            broadcastIntentLocked(null, null, intent, null, finisher,
10101                                    0, null, null, null, AppOpsManager.OP_NONE,
10102                                    true, false, MY_PID, Process.SYSTEM_UID,
10103                                    users[j]);
10104                            if (finisher != null) {
10105                                mWaitingUpdate = true;
10106                            }
10107                        }
10108                    }
10109                }
10110                if (mWaitingUpdate) {
10111                    return;
10112                }
10113                mDidUpdate = true;
10114            }
10115
10116            mAppOpsService.systemReady();
10117            mSystemReady = true;
10118        }
10119
10120        ArrayList<ProcessRecord> procsToKill = null;
10121        synchronized(mPidsSelfLocked) {
10122            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10123                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10124                if (!isAllowedWhileBooting(proc.info)){
10125                    if (procsToKill == null) {
10126                        procsToKill = new ArrayList<ProcessRecord>();
10127                    }
10128                    procsToKill.add(proc);
10129                }
10130            }
10131        }
10132
10133        synchronized(this) {
10134            if (procsToKill != null) {
10135                for (int i=procsToKill.size()-1; i>=0; i--) {
10136                    ProcessRecord proc = procsToKill.get(i);
10137                    Slog.i(TAG, "Removing system update proc: " + proc);
10138                    removeProcessLocked(proc, true, false, "system update done");
10139                }
10140            }
10141
10142            // Now that we have cleaned up any update processes, we
10143            // are ready to start launching real processes and know that
10144            // we won't trample on them any more.
10145            mProcessesReady = true;
10146        }
10147
10148        Slog.i(TAG, "System now ready");
10149        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10150            SystemClock.uptimeMillis());
10151
10152        synchronized(this) {
10153            // Make sure we have no pre-ready processes sitting around.
10154
10155            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10156                ResolveInfo ri = mContext.getPackageManager()
10157                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10158                                STOCK_PM_FLAGS);
10159                CharSequence errorMsg = null;
10160                if (ri != null) {
10161                    ActivityInfo ai = ri.activityInfo;
10162                    ApplicationInfo app = ai.applicationInfo;
10163                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10164                        mTopAction = Intent.ACTION_FACTORY_TEST;
10165                        mTopData = null;
10166                        mTopComponent = new ComponentName(app.packageName,
10167                                ai.name);
10168                    } else {
10169                        errorMsg = mContext.getResources().getText(
10170                                com.android.internal.R.string.factorytest_not_system);
10171                    }
10172                } else {
10173                    errorMsg = mContext.getResources().getText(
10174                            com.android.internal.R.string.factorytest_no_action);
10175                }
10176                if (errorMsg != null) {
10177                    mTopAction = null;
10178                    mTopData = null;
10179                    mTopComponent = null;
10180                    Message msg = Message.obtain();
10181                    msg.what = SHOW_FACTORY_ERROR_MSG;
10182                    msg.getData().putCharSequence("msg", errorMsg);
10183                    mHandler.sendMessage(msg);
10184                }
10185            }
10186        }
10187
10188        retrieveSettings();
10189
10190        synchronized (this) {
10191            readGrantedUriPermissionsLocked();
10192        }
10193
10194        if (goingCallback != null) goingCallback.run();
10195
10196        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10197                Integer.toString(mCurrentUserId), mCurrentUserId);
10198        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10199                Integer.toString(mCurrentUserId), mCurrentUserId);
10200        mSystemServiceManager.startUser(mCurrentUserId);
10201
10202        synchronized (this) {
10203            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10204                try {
10205                    List apps = AppGlobals.getPackageManager().
10206                        getPersistentApplications(STOCK_PM_FLAGS);
10207                    if (apps != null) {
10208                        int N = apps.size();
10209                        int i;
10210                        for (i=0; i<N; i++) {
10211                            ApplicationInfo info
10212                                = (ApplicationInfo)apps.get(i);
10213                            if (info != null &&
10214                                    !info.packageName.equals("android")) {
10215                                addAppLocked(info, false, null /* ABI override */);
10216                            }
10217                        }
10218                    }
10219                } catch (RemoteException ex) {
10220                    // pm is in same process, this will never happen.
10221                }
10222            }
10223
10224            // Start up initial activity.
10225            mBooting = true;
10226
10227            try {
10228                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10229                    Message msg = Message.obtain();
10230                    msg.what = SHOW_UID_ERROR_MSG;
10231                    mHandler.sendMessage(msg);
10232                }
10233            } catch (RemoteException e) {
10234            }
10235
10236            long ident = Binder.clearCallingIdentity();
10237            try {
10238                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10239                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10240                        | Intent.FLAG_RECEIVER_FOREGROUND);
10241                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10242                broadcastIntentLocked(null, null, intent,
10243                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10244                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10245                intent = new Intent(Intent.ACTION_USER_STARTING);
10246                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10247                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10248                broadcastIntentLocked(null, null, intent,
10249                        null, new IIntentReceiver.Stub() {
10250                            @Override
10251                            public void performReceive(Intent intent, int resultCode, String data,
10252                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10253                                    throws RemoteException {
10254                            }
10255                        }, 0, null, null,
10256                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10257                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10258            } catch (Throwable t) {
10259                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10260            } finally {
10261                Binder.restoreCallingIdentity(ident);
10262            }
10263            mStackSupervisor.resumeTopActivitiesLocked();
10264            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10265        }
10266    }
10267
10268    private boolean makeAppCrashingLocked(ProcessRecord app,
10269            String shortMsg, String longMsg, String stackTrace) {
10270        app.crashing = true;
10271        app.crashingReport = generateProcessError(app,
10272                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10273        startAppProblemLocked(app);
10274        app.stopFreezingAllLocked();
10275        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10276    }
10277
10278    private void makeAppNotRespondingLocked(ProcessRecord app,
10279            String activity, String shortMsg, String longMsg) {
10280        app.notResponding = true;
10281        app.notRespondingReport = generateProcessError(app,
10282                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10283                activity, shortMsg, longMsg, null);
10284        startAppProblemLocked(app);
10285        app.stopFreezingAllLocked();
10286    }
10287
10288    /**
10289     * Generate a process error record, suitable for attachment to a ProcessRecord.
10290     *
10291     * @param app The ProcessRecord in which the error occurred.
10292     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10293     *                      ActivityManager.AppErrorStateInfo
10294     * @param activity The activity associated with the crash, if known.
10295     * @param shortMsg Short message describing the crash.
10296     * @param longMsg Long message describing the crash.
10297     * @param stackTrace Full crash stack trace, may be null.
10298     *
10299     * @return Returns a fully-formed AppErrorStateInfo record.
10300     */
10301    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10302            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10303        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10304
10305        report.condition = condition;
10306        report.processName = app.processName;
10307        report.pid = app.pid;
10308        report.uid = app.info.uid;
10309        report.tag = activity;
10310        report.shortMsg = shortMsg;
10311        report.longMsg = longMsg;
10312        report.stackTrace = stackTrace;
10313
10314        return report;
10315    }
10316
10317    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10318        synchronized (this) {
10319            app.crashing = false;
10320            app.crashingReport = null;
10321            app.notResponding = false;
10322            app.notRespondingReport = null;
10323            if (app.anrDialog == fromDialog) {
10324                app.anrDialog = null;
10325            }
10326            if (app.waitDialog == fromDialog) {
10327                app.waitDialog = null;
10328            }
10329            if (app.pid > 0 && app.pid != MY_PID) {
10330                handleAppCrashLocked(app, null, null, null);
10331                killUnneededProcessLocked(app, "user request after error");
10332            }
10333        }
10334    }
10335
10336    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10337            String stackTrace) {
10338        long now = SystemClock.uptimeMillis();
10339
10340        Long crashTime;
10341        if (!app.isolated) {
10342            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10343        } else {
10344            crashTime = null;
10345        }
10346        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10347            // This process loses!
10348            Slog.w(TAG, "Process " + app.info.processName
10349                    + " has crashed too many times: killing!");
10350            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10351                    app.userId, app.info.processName, app.uid);
10352            mStackSupervisor.handleAppCrashLocked(app);
10353            if (!app.persistent) {
10354                // We don't want to start this process again until the user
10355                // explicitly does so...  but for persistent process, we really
10356                // need to keep it running.  If a persistent process is actually
10357                // repeatedly crashing, then badness for everyone.
10358                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10359                        app.info.processName);
10360                if (!app.isolated) {
10361                    // XXX We don't have a way to mark isolated processes
10362                    // as bad, since they don't have a peristent identity.
10363                    mBadProcesses.put(app.info.processName, app.uid,
10364                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10365                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10366                }
10367                app.bad = true;
10368                app.removed = true;
10369                // Don't let services in this process be restarted and potentially
10370                // annoy the user repeatedly.  Unless it is persistent, since those
10371                // processes run critical code.
10372                removeProcessLocked(app, false, false, "crash");
10373                mStackSupervisor.resumeTopActivitiesLocked();
10374                return false;
10375            }
10376            mStackSupervisor.resumeTopActivitiesLocked();
10377        } else {
10378            mStackSupervisor.finishTopRunningActivityLocked(app);
10379        }
10380
10381        // Bump up the crash count of any services currently running in the proc.
10382        for (int i=app.services.size()-1; i>=0; i--) {
10383            // Any services running in the application need to be placed
10384            // back in the pending list.
10385            ServiceRecord sr = app.services.valueAt(i);
10386            sr.crashCount++;
10387        }
10388
10389        // If the crashing process is what we consider to be the "home process" and it has been
10390        // replaced by a third-party app, clear the package preferred activities from packages
10391        // with a home activity running in the process to prevent a repeatedly crashing app
10392        // from blocking the user to manually clear the list.
10393        final ArrayList<ActivityRecord> activities = app.activities;
10394        if (app == mHomeProcess && activities.size() > 0
10395                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10396            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10397                final ActivityRecord r = activities.get(activityNdx);
10398                if (r.isHomeActivity()) {
10399                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10400                    try {
10401                        ActivityThread.getPackageManager()
10402                                .clearPackagePreferredActivities(r.packageName);
10403                    } catch (RemoteException c) {
10404                        // pm is in same process, this will never happen.
10405                    }
10406                }
10407            }
10408        }
10409
10410        if (!app.isolated) {
10411            // XXX Can't keep track of crash times for isolated processes,
10412            // because they don't have a perisistent identity.
10413            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10414        }
10415
10416        return true;
10417    }
10418
10419    void startAppProblemLocked(ProcessRecord app) {
10420        if (app.userId == mCurrentUserId) {
10421            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10422                    mContext, app.info.packageName, app.info.flags);
10423        } else {
10424            // If this app is not running under the current user, then we
10425            // can't give it a report button because that would require
10426            // launching the report UI under a different user.
10427            app.errorReportReceiver = null;
10428        }
10429        skipCurrentReceiverLocked(app);
10430    }
10431
10432    void skipCurrentReceiverLocked(ProcessRecord app) {
10433        for (BroadcastQueue queue : mBroadcastQueues) {
10434            queue.skipCurrentReceiverLocked(app);
10435        }
10436    }
10437
10438    /**
10439     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10440     * The application process will exit immediately after this call returns.
10441     * @param app object of the crashing app, null for the system server
10442     * @param crashInfo describing the exception
10443     */
10444    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10445        ProcessRecord r = findAppProcess(app, "Crash");
10446        final String processName = app == null ? "system_server"
10447                : (r == null ? "unknown" : r.processName);
10448
10449        handleApplicationCrashInner("crash", r, processName, crashInfo);
10450    }
10451
10452    /* Native crash reporting uses this inner version because it needs to be somewhat
10453     * decoupled from the AM-managed cleanup lifecycle
10454     */
10455    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10456            ApplicationErrorReport.CrashInfo crashInfo) {
10457        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10458                UserHandle.getUserId(Binder.getCallingUid()), processName,
10459                r == null ? -1 : r.info.flags,
10460                crashInfo.exceptionClassName,
10461                crashInfo.exceptionMessage,
10462                crashInfo.throwFileName,
10463                crashInfo.throwLineNumber);
10464
10465        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10466
10467        crashApplication(r, crashInfo);
10468    }
10469
10470    public void handleApplicationStrictModeViolation(
10471            IBinder app,
10472            int violationMask,
10473            StrictMode.ViolationInfo info) {
10474        ProcessRecord r = findAppProcess(app, "StrictMode");
10475        if (r == null) {
10476            return;
10477        }
10478
10479        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10480            Integer stackFingerprint = info.hashCode();
10481            boolean logIt = true;
10482            synchronized (mAlreadyLoggedViolatedStacks) {
10483                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10484                    logIt = false;
10485                    // TODO: sub-sample into EventLog for these, with
10486                    // the info.durationMillis?  Then we'd get
10487                    // the relative pain numbers, without logging all
10488                    // the stack traces repeatedly.  We'd want to do
10489                    // likewise in the client code, which also does
10490                    // dup suppression, before the Binder call.
10491                } else {
10492                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10493                        mAlreadyLoggedViolatedStacks.clear();
10494                    }
10495                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10496                }
10497            }
10498            if (logIt) {
10499                logStrictModeViolationToDropBox(r, info);
10500            }
10501        }
10502
10503        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10504            AppErrorResult result = new AppErrorResult();
10505            synchronized (this) {
10506                final long origId = Binder.clearCallingIdentity();
10507
10508                Message msg = Message.obtain();
10509                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10510                HashMap<String, Object> data = new HashMap<String, Object>();
10511                data.put("result", result);
10512                data.put("app", r);
10513                data.put("violationMask", violationMask);
10514                data.put("info", info);
10515                msg.obj = data;
10516                mHandler.sendMessage(msg);
10517
10518                Binder.restoreCallingIdentity(origId);
10519            }
10520            int res = result.get();
10521            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10522        }
10523    }
10524
10525    // Depending on the policy in effect, there could be a bunch of
10526    // these in quick succession so we try to batch these together to
10527    // minimize disk writes, number of dropbox entries, and maximize
10528    // compression, by having more fewer, larger records.
10529    private void logStrictModeViolationToDropBox(
10530            ProcessRecord process,
10531            StrictMode.ViolationInfo info) {
10532        if (info == null) {
10533            return;
10534        }
10535        final boolean isSystemApp = process == null ||
10536                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10537                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10538        final String processName = process == null ? "unknown" : process.processName;
10539        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10540        final DropBoxManager dbox = (DropBoxManager)
10541                mContext.getSystemService(Context.DROPBOX_SERVICE);
10542
10543        // Exit early if the dropbox isn't configured to accept this report type.
10544        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10545
10546        boolean bufferWasEmpty;
10547        boolean needsFlush;
10548        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10549        synchronized (sb) {
10550            bufferWasEmpty = sb.length() == 0;
10551            appendDropBoxProcessHeaders(process, processName, sb);
10552            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10553            sb.append("System-App: ").append(isSystemApp).append("\n");
10554            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10555            if (info.violationNumThisLoop != 0) {
10556                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10557            }
10558            if (info.numAnimationsRunning != 0) {
10559                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10560            }
10561            if (info.broadcastIntentAction != null) {
10562                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10563            }
10564            if (info.durationMillis != -1) {
10565                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10566            }
10567            if (info.numInstances != -1) {
10568                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10569            }
10570            if (info.tags != null) {
10571                for (String tag : info.tags) {
10572                    sb.append("Span-Tag: ").append(tag).append("\n");
10573                }
10574            }
10575            sb.append("\n");
10576            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10577                sb.append(info.crashInfo.stackTrace);
10578            }
10579            sb.append("\n");
10580
10581            // Only buffer up to ~64k.  Various logging bits truncate
10582            // things at 128k.
10583            needsFlush = (sb.length() > 64 * 1024);
10584        }
10585
10586        // Flush immediately if the buffer's grown too large, or this
10587        // is a non-system app.  Non-system apps are isolated with a
10588        // different tag & policy and not batched.
10589        //
10590        // Batching is useful during internal testing with
10591        // StrictMode settings turned up high.  Without batching,
10592        // thousands of separate files could be created on boot.
10593        if (!isSystemApp || needsFlush) {
10594            new Thread("Error dump: " + dropboxTag) {
10595                @Override
10596                public void run() {
10597                    String report;
10598                    synchronized (sb) {
10599                        report = sb.toString();
10600                        sb.delete(0, sb.length());
10601                        sb.trimToSize();
10602                    }
10603                    if (report.length() != 0) {
10604                        dbox.addText(dropboxTag, report);
10605                    }
10606                }
10607            }.start();
10608            return;
10609        }
10610
10611        // System app batching:
10612        if (!bufferWasEmpty) {
10613            // An existing dropbox-writing thread is outstanding, so
10614            // we don't need to start it up.  The existing thread will
10615            // catch the buffer appends we just did.
10616            return;
10617        }
10618
10619        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10620        // (After this point, we shouldn't access AMS internal data structures.)
10621        new Thread("Error dump: " + dropboxTag) {
10622            @Override
10623            public void run() {
10624                // 5 second sleep to let stacks arrive and be batched together
10625                try {
10626                    Thread.sleep(5000);  // 5 seconds
10627                } catch (InterruptedException e) {}
10628
10629                String errorReport;
10630                synchronized (mStrictModeBuffer) {
10631                    errorReport = mStrictModeBuffer.toString();
10632                    if (errorReport.length() == 0) {
10633                        return;
10634                    }
10635                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10636                    mStrictModeBuffer.trimToSize();
10637                }
10638                dbox.addText(dropboxTag, errorReport);
10639            }
10640        }.start();
10641    }
10642
10643    /**
10644     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10645     * @param app object of the crashing app, null for the system server
10646     * @param tag reported by the caller
10647     * @param crashInfo describing the context of the error
10648     * @return true if the process should exit immediately (WTF is fatal)
10649     */
10650    public boolean handleApplicationWtf(IBinder app, String tag,
10651            ApplicationErrorReport.CrashInfo crashInfo) {
10652        ProcessRecord r = findAppProcess(app, "WTF");
10653        final String processName = app == null ? "system_server"
10654                : (r == null ? "unknown" : r.processName);
10655
10656        EventLog.writeEvent(EventLogTags.AM_WTF,
10657                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10658                processName,
10659                r == null ? -1 : r.info.flags,
10660                tag, crashInfo.exceptionMessage);
10661
10662        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10663
10664        if (r != null && r.pid != Process.myPid() &&
10665                Settings.Global.getInt(mContext.getContentResolver(),
10666                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10667            crashApplication(r, crashInfo);
10668            return true;
10669        } else {
10670            return false;
10671        }
10672    }
10673
10674    /**
10675     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10676     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10677     */
10678    private ProcessRecord findAppProcess(IBinder app, String reason) {
10679        if (app == null) {
10680            return null;
10681        }
10682
10683        synchronized (this) {
10684            final int NP = mProcessNames.getMap().size();
10685            for (int ip=0; ip<NP; ip++) {
10686                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10687                final int NA = apps.size();
10688                for (int ia=0; ia<NA; ia++) {
10689                    ProcessRecord p = apps.valueAt(ia);
10690                    if (p.thread != null && p.thread.asBinder() == app) {
10691                        return p;
10692                    }
10693                }
10694            }
10695
10696            Slog.w(TAG, "Can't find mystery application for " + reason
10697                    + " from pid=" + Binder.getCallingPid()
10698                    + " uid=" + Binder.getCallingUid() + ": " + app);
10699            return null;
10700        }
10701    }
10702
10703    /**
10704     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10705     * to append various headers to the dropbox log text.
10706     */
10707    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10708            StringBuilder sb) {
10709        // Watchdog thread ends up invoking this function (with
10710        // a null ProcessRecord) to add the stack file to dropbox.
10711        // Do not acquire a lock on this (am) in such cases, as it
10712        // could cause a potential deadlock, if and when watchdog
10713        // is invoked due to unavailability of lock on am and it
10714        // would prevent watchdog from killing system_server.
10715        if (process == null) {
10716            sb.append("Process: ").append(processName).append("\n");
10717            return;
10718        }
10719        // Note: ProcessRecord 'process' is guarded by the service
10720        // instance.  (notably process.pkgList, which could otherwise change
10721        // concurrently during execution of this method)
10722        synchronized (this) {
10723            sb.append("Process: ").append(processName).append("\n");
10724            int flags = process.info.flags;
10725            IPackageManager pm = AppGlobals.getPackageManager();
10726            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10727            for (int ip=0; ip<process.pkgList.size(); ip++) {
10728                String pkg = process.pkgList.keyAt(ip);
10729                sb.append("Package: ").append(pkg);
10730                try {
10731                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10732                    if (pi != null) {
10733                        sb.append(" v").append(pi.versionCode);
10734                        if (pi.versionName != null) {
10735                            sb.append(" (").append(pi.versionName).append(")");
10736                        }
10737                    }
10738                } catch (RemoteException e) {
10739                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10740                }
10741                sb.append("\n");
10742            }
10743        }
10744    }
10745
10746    private static String processClass(ProcessRecord process) {
10747        if (process == null || process.pid == MY_PID) {
10748            return "system_server";
10749        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10750            return "system_app";
10751        } else {
10752            return "data_app";
10753        }
10754    }
10755
10756    /**
10757     * Write a description of an error (crash, WTF, ANR) to the drop box.
10758     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10759     * @param process which caused the error, null means the system server
10760     * @param activity which triggered the error, null if unknown
10761     * @param parent activity related to the error, null if unknown
10762     * @param subject line related to the error, null if absent
10763     * @param report in long form describing the error, null if absent
10764     * @param logFile to include in the report, null if none
10765     * @param crashInfo giving an application stack trace, null if absent
10766     */
10767    public void addErrorToDropBox(String eventType,
10768            ProcessRecord process, String processName, ActivityRecord activity,
10769            ActivityRecord parent, String subject,
10770            final String report, final File logFile,
10771            final ApplicationErrorReport.CrashInfo crashInfo) {
10772        // NOTE -- this must never acquire the ActivityManagerService lock,
10773        // otherwise the watchdog may be prevented from resetting the system.
10774
10775        final String dropboxTag = processClass(process) + "_" + eventType;
10776        final DropBoxManager dbox = (DropBoxManager)
10777                mContext.getSystemService(Context.DROPBOX_SERVICE);
10778
10779        // Exit early if the dropbox isn't configured to accept this report type.
10780        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10781
10782        final StringBuilder sb = new StringBuilder(1024);
10783        appendDropBoxProcessHeaders(process, processName, sb);
10784        if (activity != null) {
10785            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10786        }
10787        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10788            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10789        }
10790        if (parent != null && parent != activity) {
10791            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10792        }
10793        if (subject != null) {
10794            sb.append("Subject: ").append(subject).append("\n");
10795        }
10796        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10797        if (Debug.isDebuggerConnected()) {
10798            sb.append("Debugger: Connected\n");
10799        }
10800        sb.append("\n");
10801
10802        // Do the rest in a worker thread to avoid blocking the caller on I/O
10803        // (After this point, we shouldn't access AMS internal data structures.)
10804        Thread worker = new Thread("Error dump: " + dropboxTag) {
10805            @Override
10806            public void run() {
10807                if (report != null) {
10808                    sb.append(report);
10809                }
10810                if (logFile != null) {
10811                    try {
10812                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10813                                    "\n\n[[TRUNCATED]]"));
10814                    } catch (IOException e) {
10815                        Slog.e(TAG, "Error reading " + logFile, e);
10816                    }
10817                }
10818                if (crashInfo != null && crashInfo.stackTrace != null) {
10819                    sb.append(crashInfo.stackTrace);
10820                }
10821
10822                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10823                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10824                if (lines > 0) {
10825                    sb.append("\n");
10826
10827                    // Merge several logcat streams, and take the last N lines
10828                    InputStreamReader input = null;
10829                    try {
10830                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10831                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10832                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10833
10834                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10835                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10836                        input = new InputStreamReader(logcat.getInputStream());
10837
10838                        int num;
10839                        char[] buf = new char[8192];
10840                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10841                    } catch (IOException e) {
10842                        Slog.e(TAG, "Error running logcat", e);
10843                    } finally {
10844                        if (input != null) try { input.close(); } catch (IOException e) {}
10845                    }
10846                }
10847
10848                dbox.addText(dropboxTag, sb.toString());
10849            }
10850        };
10851
10852        if (process == null) {
10853            // If process is null, we are being called from some internal code
10854            // and may be about to die -- run this synchronously.
10855            worker.run();
10856        } else {
10857            worker.start();
10858        }
10859    }
10860
10861    /**
10862     * Bring up the "unexpected error" dialog box for a crashing app.
10863     * Deal with edge cases (intercepts from instrumented applications,
10864     * ActivityController, error intent receivers, that sort of thing).
10865     * @param r the application crashing
10866     * @param crashInfo describing the failure
10867     */
10868    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10869        long timeMillis = System.currentTimeMillis();
10870        String shortMsg = crashInfo.exceptionClassName;
10871        String longMsg = crashInfo.exceptionMessage;
10872        String stackTrace = crashInfo.stackTrace;
10873        if (shortMsg != null && longMsg != null) {
10874            longMsg = shortMsg + ": " + longMsg;
10875        } else if (shortMsg != null) {
10876            longMsg = shortMsg;
10877        }
10878
10879        AppErrorResult result = new AppErrorResult();
10880        synchronized (this) {
10881            if (mController != null) {
10882                try {
10883                    String name = r != null ? r.processName : null;
10884                    int pid = r != null ? r.pid : Binder.getCallingPid();
10885                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10886                    if (!mController.appCrashed(name, pid,
10887                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10888                        Slog.w(TAG, "Force-killing crashed app " + name
10889                                + " at watcher's request");
10890                        Process.killProcess(pid);
10891                        if (r != null) {
10892                            Process.killProcessGroup(uid, pid);
10893                        }
10894                        return;
10895                    }
10896                } catch (RemoteException e) {
10897                    mController = null;
10898                    Watchdog.getInstance().setActivityController(null);
10899                }
10900            }
10901
10902            final long origId = Binder.clearCallingIdentity();
10903
10904            // If this process is running instrumentation, finish it.
10905            if (r != null && r.instrumentationClass != null) {
10906                Slog.w(TAG, "Error in app " + r.processName
10907                      + " running instrumentation " + r.instrumentationClass + ":");
10908                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10909                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10910                Bundle info = new Bundle();
10911                info.putString("shortMsg", shortMsg);
10912                info.putString("longMsg", longMsg);
10913                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10914                Binder.restoreCallingIdentity(origId);
10915                return;
10916            }
10917
10918            // If we can't identify the process or it's already exceeded its crash quota,
10919            // quit right away without showing a crash dialog.
10920            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10921                Binder.restoreCallingIdentity(origId);
10922                return;
10923            }
10924
10925            Message msg = Message.obtain();
10926            msg.what = SHOW_ERROR_MSG;
10927            HashMap data = new HashMap();
10928            data.put("result", result);
10929            data.put("app", r);
10930            msg.obj = data;
10931            mHandler.sendMessage(msg);
10932
10933            Binder.restoreCallingIdentity(origId);
10934        }
10935
10936        int res = result.get();
10937
10938        Intent appErrorIntent = null;
10939        synchronized (this) {
10940            if (r != null && !r.isolated) {
10941                // XXX Can't keep track of crash time for isolated processes,
10942                // since they don't have a persistent identity.
10943                mProcessCrashTimes.put(r.info.processName, r.uid,
10944                        SystemClock.uptimeMillis());
10945            }
10946            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10947                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10948            }
10949        }
10950
10951        if (appErrorIntent != null) {
10952            try {
10953                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10954            } catch (ActivityNotFoundException e) {
10955                Slog.w(TAG, "bug report receiver dissappeared", e);
10956            }
10957        }
10958    }
10959
10960    Intent createAppErrorIntentLocked(ProcessRecord r,
10961            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10962        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10963        if (report == null) {
10964            return null;
10965        }
10966        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10967        result.setComponent(r.errorReportReceiver);
10968        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10969        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10970        return result;
10971    }
10972
10973    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10974            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10975        if (r.errorReportReceiver == null) {
10976            return null;
10977        }
10978
10979        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10980            return null;
10981        }
10982
10983        ApplicationErrorReport report = new ApplicationErrorReport();
10984        report.packageName = r.info.packageName;
10985        report.installerPackageName = r.errorReportReceiver.getPackageName();
10986        report.processName = r.processName;
10987        report.time = timeMillis;
10988        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10989
10990        if (r.crashing || r.forceCrashReport) {
10991            report.type = ApplicationErrorReport.TYPE_CRASH;
10992            report.crashInfo = crashInfo;
10993        } else if (r.notResponding) {
10994            report.type = ApplicationErrorReport.TYPE_ANR;
10995            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10996
10997            report.anrInfo.activity = r.notRespondingReport.tag;
10998            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10999            report.anrInfo.info = r.notRespondingReport.longMsg;
11000        }
11001
11002        return report;
11003    }
11004
11005    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11006        enforceNotIsolatedCaller("getProcessesInErrorState");
11007        // assume our apps are happy - lazy create the list
11008        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11009
11010        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11011                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11012        int userId = UserHandle.getUserId(Binder.getCallingUid());
11013
11014        synchronized (this) {
11015
11016            // iterate across all processes
11017            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11018                ProcessRecord app = mLruProcesses.get(i);
11019                if (!allUsers && app.userId != userId) {
11020                    continue;
11021                }
11022                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11023                    // This one's in trouble, so we'll generate a report for it
11024                    // crashes are higher priority (in case there's a crash *and* an anr)
11025                    ActivityManager.ProcessErrorStateInfo report = null;
11026                    if (app.crashing) {
11027                        report = app.crashingReport;
11028                    } else if (app.notResponding) {
11029                        report = app.notRespondingReport;
11030                    }
11031
11032                    if (report != null) {
11033                        if (errList == null) {
11034                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11035                        }
11036                        errList.add(report);
11037                    } else {
11038                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11039                                " crashing = " + app.crashing +
11040                                " notResponding = " + app.notResponding);
11041                    }
11042                }
11043            }
11044        }
11045
11046        return errList;
11047    }
11048
11049    static int procStateToImportance(int procState, int memAdj,
11050            ActivityManager.RunningAppProcessInfo currApp) {
11051        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11052        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11053            currApp.lru = memAdj;
11054        } else {
11055            currApp.lru = 0;
11056        }
11057        return imp;
11058    }
11059
11060    private void fillInProcMemInfo(ProcessRecord app,
11061            ActivityManager.RunningAppProcessInfo outInfo) {
11062        outInfo.pid = app.pid;
11063        outInfo.uid = app.info.uid;
11064        if (mHeavyWeightProcess == app) {
11065            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11066        }
11067        if (app.persistent) {
11068            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11069        }
11070        if (app.activities.size() > 0) {
11071            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11072        }
11073        outInfo.lastTrimLevel = app.trimMemoryLevel;
11074        int adj = app.curAdj;
11075        int procState = app.curProcState;
11076        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11077        outInfo.importanceReasonCode = app.adjTypeCode;
11078        outInfo.processState = app.curProcState;
11079    }
11080
11081    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11082        enforceNotIsolatedCaller("getRunningAppProcesses");
11083        // Lazy instantiation of list
11084        List<ActivityManager.RunningAppProcessInfo> runList = null;
11085        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11086                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11087        int userId = UserHandle.getUserId(Binder.getCallingUid());
11088        synchronized (this) {
11089            // Iterate across all processes
11090            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11091                ProcessRecord app = mLruProcesses.get(i);
11092                if (!allUsers && app.userId != userId) {
11093                    continue;
11094                }
11095                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11096                    // Generate process state info for running application
11097                    ActivityManager.RunningAppProcessInfo currApp =
11098                        new ActivityManager.RunningAppProcessInfo(app.processName,
11099                                app.pid, app.getPackageList());
11100                    fillInProcMemInfo(app, currApp);
11101                    if (app.adjSource instanceof ProcessRecord) {
11102                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11103                        currApp.importanceReasonImportance =
11104                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11105                                        app.adjSourceProcState);
11106                    } else if (app.adjSource instanceof ActivityRecord) {
11107                        ActivityRecord r = (ActivityRecord)app.adjSource;
11108                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11109                    }
11110                    if (app.adjTarget instanceof ComponentName) {
11111                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11112                    }
11113                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11114                    //        + " lru=" + currApp.lru);
11115                    if (runList == null) {
11116                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11117                    }
11118                    runList.add(currApp);
11119                }
11120            }
11121        }
11122        return runList;
11123    }
11124
11125    public List<ApplicationInfo> getRunningExternalApplications() {
11126        enforceNotIsolatedCaller("getRunningExternalApplications");
11127        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11128        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11129        if (runningApps != null && runningApps.size() > 0) {
11130            Set<String> extList = new HashSet<String>();
11131            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11132                if (app.pkgList != null) {
11133                    for (String pkg : app.pkgList) {
11134                        extList.add(pkg);
11135                    }
11136                }
11137            }
11138            IPackageManager pm = AppGlobals.getPackageManager();
11139            for (String pkg : extList) {
11140                try {
11141                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11142                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11143                        retList.add(info);
11144                    }
11145                } catch (RemoteException e) {
11146                }
11147            }
11148        }
11149        return retList;
11150    }
11151
11152    @Override
11153    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11154        enforceNotIsolatedCaller("getMyMemoryState");
11155        synchronized (this) {
11156            ProcessRecord proc;
11157            synchronized (mPidsSelfLocked) {
11158                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11159            }
11160            fillInProcMemInfo(proc, outInfo);
11161        }
11162    }
11163
11164    @Override
11165    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11166        if (checkCallingPermission(android.Manifest.permission.DUMP)
11167                != PackageManager.PERMISSION_GRANTED) {
11168            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11169                    + Binder.getCallingPid()
11170                    + ", uid=" + Binder.getCallingUid()
11171                    + " without permission "
11172                    + android.Manifest.permission.DUMP);
11173            return;
11174        }
11175
11176        boolean dumpAll = false;
11177        boolean dumpClient = false;
11178        String dumpPackage = null;
11179
11180        int opti = 0;
11181        while (opti < args.length) {
11182            String opt = args[opti];
11183            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11184                break;
11185            }
11186            opti++;
11187            if ("-a".equals(opt)) {
11188                dumpAll = true;
11189            } else if ("-c".equals(opt)) {
11190                dumpClient = true;
11191            } else if ("-h".equals(opt)) {
11192                pw.println("Activity manager dump options:");
11193                pw.println("  [-a] [-c] [-h] [cmd] ...");
11194                pw.println("  cmd may be one of:");
11195                pw.println("    a[ctivities]: activity stack state");
11196                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11197                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11198                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11199                pw.println("    o[om]: out of memory management");
11200                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11201                pw.println("    provider [COMP_SPEC]: provider client-side state");
11202                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11203                pw.println("    service [COMP_SPEC]: service client-side state");
11204                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11205                pw.println("    all: dump all activities");
11206                pw.println("    top: dump the top activity");
11207                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11208                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11209                pw.println("    a partial substring in a component name, a");
11210                pw.println("    hex object identifier.");
11211                pw.println("  -a: include all available server state.");
11212                pw.println("  -c: include client state.");
11213                return;
11214            } else {
11215                pw.println("Unknown argument: " + opt + "; use -h for help");
11216            }
11217        }
11218
11219        long origId = Binder.clearCallingIdentity();
11220        boolean more = false;
11221        // Is the caller requesting to dump a particular piece of data?
11222        if (opti < args.length) {
11223            String cmd = args[opti];
11224            opti++;
11225            if ("activities".equals(cmd) || "a".equals(cmd)) {
11226                synchronized (this) {
11227                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11228                }
11229            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11230                String[] newArgs;
11231                String name;
11232                if (opti >= args.length) {
11233                    name = null;
11234                    newArgs = EMPTY_STRING_ARRAY;
11235                } else {
11236                    name = args[opti];
11237                    opti++;
11238                    newArgs = new String[args.length - opti];
11239                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11240                            args.length - opti);
11241                }
11242                synchronized (this) {
11243                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11244                }
11245            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11246                String[] newArgs;
11247                String name;
11248                if (opti >= args.length) {
11249                    name = null;
11250                    newArgs = EMPTY_STRING_ARRAY;
11251                } else {
11252                    name = args[opti];
11253                    opti++;
11254                    newArgs = new String[args.length - opti];
11255                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11256                            args.length - opti);
11257                }
11258                synchronized (this) {
11259                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11260                }
11261            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11262                String[] newArgs;
11263                String name;
11264                if (opti >= args.length) {
11265                    name = null;
11266                    newArgs = EMPTY_STRING_ARRAY;
11267                } else {
11268                    name = args[opti];
11269                    opti++;
11270                    newArgs = new String[args.length - opti];
11271                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11272                            args.length - opti);
11273                }
11274                synchronized (this) {
11275                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11276                }
11277            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11278                synchronized (this) {
11279                    dumpOomLocked(fd, pw, args, opti, true);
11280                }
11281            } else if ("provider".equals(cmd)) {
11282                String[] newArgs;
11283                String name;
11284                if (opti >= args.length) {
11285                    name = null;
11286                    newArgs = EMPTY_STRING_ARRAY;
11287                } else {
11288                    name = args[opti];
11289                    opti++;
11290                    newArgs = new String[args.length - opti];
11291                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11292                }
11293                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11294                    pw.println("No providers match: " + name);
11295                    pw.println("Use -h for help.");
11296                }
11297            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11298                synchronized (this) {
11299                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11300                }
11301            } else if ("service".equals(cmd)) {
11302                String[] newArgs;
11303                String name;
11304                if (opti >= args.length) {
11305                    name = null;
11306                    newArgs = EMPTY_STRING_ARRAY;
11307                } else {
11308                    name = args[opti];
11309                    opti++;
11310                    newArgs = new String[args.length - opti];
11311                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11312                            args.length - opti);
11313                }
11314                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11315                    pw.println("No services match: " + name);
11316                    pw.println("Use -h for help.");
11317                }
11318            } else if ("package".equals(cmd)) {
11319                String[] newArgs;
11320                if (opti >= args.length) {
11321                    pw.println("package: no package name specified");
11322                    pw.println("Use -h for help.");
11323                } else {
11324                    dumpPackage = args[opti];
11325                    opti++;
11326                    newArgs = new String[args.length - opti];
11327                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11328                            args.length - opti);
11329                    args = newArgs;
11330                    opti = 0;
11331                    more = true;
11332                }
11333            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11334                synchronized (this) {
11335                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11336                }
11337            } else {
11338                // Dumping a single activity?
11339                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11340                    pw.println("Bad activity command, or no activities match: " + cmd);
11341                    pw.println("Use -h for help.");
11342                }
11343            }
11344            if (!more) {
11345                Binder.restoreCallingIdentity(origId);
11346                return;
11347            }
11348        }
11349
11350        // No piece of data specified, dump everything.
11351        synchronized (this) {
11352            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11353            pw.println();
11354            if (dumpAll) {
11355                pw.println("-------------------------------------------------------------------------------");
11356            }
11357            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11358            pw.println();
11359            if (dumpAll) {
11360                pw.println("-------------------------------------------------------------------------------");
11361            }
11362            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11363            pw.println();
11364            if (dumpAll) {
11365                pw.println("-------------------------------------------------------------------------------");
11366            }
11367            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11368            pw.println();
11369            if (dumpAll) {
11370                pw.println("-------------------------------------------------------------------------------");
11371            }
11372            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11373            pw.println();
11374            if (dumpAll) {
11375                pw.println("-------------------------------------------------------------------------------");
11376            }
11377            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11378        }
11379        Binder.restoreCallingIdentity(origId);
11380    }
11381
11382    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11383            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11384        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11385
11386        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11387                dumpPackage);
11388        boolean needSep = printedAnything;
11389
11390        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11391                dumpPackage, needSep, "  mFocusedActivity: ");
11392        if (printed) {
11393            printedAnything = true;
11394            needSep = false;
11395        }
11396
11397        if (dumpPackage == null) {
11398            if (needSep) {
11399                pw.println();
11400            }
11401            needSep = true;
11402            printedAnything = true;
11403            mStackSupervisor.dump(pw, "  ");
11404        }
11405
11406        if (mRecentTasks.size() > 0) {
11407            boolean printedHeader = false;
11408
11409            final int N = mRecentTasks.size();
11410            for (int i=0; i<N; i++) {
11411                TaskRecord tr = mRecentTasks.get(i);
11412                if (dumpPackage != null) {
11413                    if (tr.realActivity == null ||
11414                            !dumpPackage.equals(tr.realActivity)) {
11415                        continue;
11416                    }
11417                }
11418                if (!printedHeader) {
11419                    if (needSep) {
11420                        pw.println();
11421                    }
11422                    pw.println("  Recent tasks:");
11423                    printedHeader = true;
11424                    printedAnything = true;
11425                }
11426                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11427                        pw.println(tr);
11428                if (dumpAll) {
11429                    mRecentTasks.get(i).dump(pw, "    ");
11430                }
11431            }
11432        }
11433
11434        if (!printedAnything) {
11435            pw.println("  (nothing)");
11436        }
11437    }
11438
11439    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11440            int opti, boolean dumpAll, String dumpPackage) {
11441        boolean needSep = false;
11442        boolean printedAnything = false;
11443        int numPers = 0;
11444
11445        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11446
11447        if (dumpAll) {
11448            final int NP = mProcessNames.getMap().size();
11449            for (int ip=0; ip<NP; ip++) {
11450                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11451                final int NA = procs.size();
11452                for (int ia=0; ia<NA; ia++) {
11453                    ProcessRecord r = procs.valueAt(ia);
11454                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11455                        continue;
11456                    }
11457                    if (!needSep) {
11458                        pw.println("  All known processes:");
11459                        needSep = true;
11460                        printedAnything = true;
11461                    }
11462                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11463                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11464                        pw.print(" "); pw.println(r);
11465                    r.dump(pw, "    ");
11466                    if (r.persistent) {
11467                        numPers++;
11468                    }
11469                }
11470            }
11471        }
11472
11473        if (mIsolatedProcesses.size() > 0) {
11474            boolean printed = false;
11475            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11476                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11477                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11478                    continue;
11479                }
11480                if (!printed) {
11481                    if (needSep) {
11482                        pw.println();
11483                    }
11484                    pw.println("  Isolated process list (sorted by uid):");
11485                    printedAnything = true;
11486                    printed = true;
11487                    needSep = true;
11488                }
11489                pw.println(String.format("%sIsolated #%2d: %s",
11490                        "    ", i, r.toString()));
11491            }
11492        }
11493
11494        if (mLruProcesses.size() > 0) {
11495            if (needSep) {
11496                pw.println();
11497            }
11498            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11499                    pw.print(" total, non-act at ");
11500                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11501                    pw.print(", non-svc at ");
11502                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11503                    pw.println("):");
11504            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11505            needSep = true;
11506            printedAnything = true;
11507        }
11508
11509        if (dumpAll || dumpPackage != null) {
11510            synchronized (mPidsSelfLocked) {
11511                boolean printed = false;
11512                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11513                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11514                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11515                        continue;
11516                    }
11517                    if (!printed) {
11518                        if (needSep) pw.println();
11519                        needSep = true;
11520                        pw.println("  PID mappings:");
11521                        printed = true;
11522                        printedAnything = true;
11523                    }
11524                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11525                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11526                }
11527            }
11528        }
11529
11530        if (mForegroundProcesses.size() > 0) {
11531            synchronized (mPidsSelfLocked) {
11532                boolean printed = false;
11533                for (int i=0; i<mForegroundProcesses.size(); i++) {
11534                    ProcessRecord r = mPidsSelfLocked.get(
11535                            mForegroundProcesses.valueAt(i).pid);
11536                    if (dumpPackage != null && (r == null
11537                            || !r.pkgList.containsKey(dumpPackage))) {
11538                        continue;
11539                    }
11540                    if (!printed) {
11541                        if (needSep) pw.println();
11542                        needSep = true;
11543                        pw.println("  Foreground Processes:");
11544                        printed = true;
11545                        printedAnything = true;
11546                    }
11547                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11548                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11549                }
11550            }
11551        }
11552
11553        if (mPersistentStartingProcesses.size() > 0) {
11554            if (needSep) pw.println();
11555            needSep = true;
11556            printedAnything = true;
11557            pw.println("  Persisent processes that are starting:");
11558            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11559                    "Starting Norm", "Restarting PERS", dumpPackage);
11560        }
11561
11562        if (mRemovedProcesses.size() > 0) {
11563            if (needSep) pw.println();
11564            needSep = true;
11565            printedAnything = true;
11566            pw.println("  Processes that are being removed:");
11567            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11568                    "Removed Norm", "Removed PERS", dumpPackage);
11569        }
11570
11571        if (mProcessesOnHold.size() > 0) {
11572            if (needSep) pw.println();
11573            needSep = true;
11574            printedAnything = true;
11575            pw.println("  Processes that are on old until the system is ready:");
11576            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11577                    "OnHold Norm", "OnHold PERS", dumpPackage);
11578        }
11579
11580        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11581
11582        if (mProcessCrashTimes.getMap().size() > 0) {
11583            boolean printed = false;
11584            long now = SystemClock.uptimeMillis();
11585            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11586            final int NP = pmap.size();
11587            for (int ip=0; ip<NP; ip++) {
11588                String pname = pmap.keyAt(ip);
11589                SparseArray<Long> uids = pmap.valueAt(ip);
11590                final int N = uids.size();
11591                for (int i=0; i<N; i++) {
11592                    int puid = uids.keyAt(i);
11593                    ProcessRecord r = mProcessNames.get(pname, puid);
11594                    if (dumpPackage != null && (r == null
11595                            || !r.pkgList.containsKey(dumpPackage))) {
11596                        continue;
11597                    }
11598                    if (!printed) {
11599                        if (needSep) pw.println();
11600                        needSep = true;
11601                        pw.println("  Time since processes crashed:");
11602                        printed = true;
11603                        printedAnything = true;
11604                    }
11605                    pw.print("    Process "); pw.print(pname);
11606                            pw.print(" uid "); pw.print(puid);
11607                            pw.print(": last crashed ");
11608                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11609                            pw.println(" ago");
11610                }
11611            }
11612        }
11613
11614        if (mBadProcesses.getMap().size() > 0) {
11615            boolean printed = false;
11616            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11617            final int NP = pmap.size();
11618            for (int ip=0; ip<NP; ip++) {
11619                String pname = pmap.keyAt(ip);
11620                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11621                final int N = uids.size();
11622                for (int i=0; i<N; i++) {
11623                    int puid = uids.keyAt(i);
11624                    ProcessRecord r = mProcessNames.get(pname, puid);
11625                    if (dumpPackage != null && (r == null
11626                            || !r.pkgList.containsKey(dumpPackage))) {
11627                        continue;
11628                    }
11629                    if (!printed) {
11630                        if (needSep) pw.println();
11631                        needSep = true;
11632                        pw.println("  Bad processes:");
11633                        printedAnything = true;
11634                    }
11635                    BadProcessInfo info = uids.valueAt(i);
11636                    pw.print("    Bad process "); pw.print(pname);
11637                            pw.print(" uid "); pw.print(puid);
11638                            pw.print(": crashed at time "); pw.println(info.time);
11639                    if (info.shortMsg != null) {
11640                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11641                    }
11642                    if (info.longMsg != null) {
11643                        pw.print("      Long msg: "); pw.println(info.longMsg);
11644                    }
11645                    if (info.stack != null) {
11646                        pw.println("      Stack:");
11647                        int lastPos = 0;
11648                        for (int pos=0; pos<info.stack.length(); pos++) {
11649                            if (info.stack.charAt(pos) == '\n') {
11650                                pw.print("        ");
11651                                pw.write(info.stack, lastPos, pos-lastPos);
11652                                pw.println();
11653                                lastPos = pos+1;
11654                            }
11655                        }
11656                        if (lastPos < info.stack.length()) {
11657                            pw.print("        ");
11658                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11659                            pw.println();
11660                        }
11661                    }
11662                }
11663            }
11664        }
11665
11666        if (dumpPackage == null) {
11667            pw.println();
11668            needSep = false;
11669            pw.println("  mStartedUsers:");
11670            for (int i=0; i<mStartedUsers.size(); i++) {
11671                UserStartedState uss = mStartedUsers.valueAt(i);
11672                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11673                        pw.print(": "); uss.dump("", pw);
11674            }
11675            pw.print("  mStartedUserArray: [");
11676            for (int i=0; i<mStartedUserArray.length; i++) {
11677                if (i > 0) pw.print(", ");
11678                pw.print(mStartedUserArray[i]);
11679            }
11680            pw.println("]");
11681            pw.print("  mUserLru: [");
11682            for (int i=0; i<mUserLru.size(); i++) {
11683                if (i > 0) pw.print(", ");
11684                pw.print(mUserLru.get(i));
11685            }
11686            pw.println("]");
11687            if (dumpAll) {
11688                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11689            }
11690            synchronized (mUserProfileGroupIdsSelfLocked) {
11691                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11692                    pw.println("  mUserProfileGroupIds:");
11693                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11694                        pw.print("    User #");
11695                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11696                        pw.print(" -> profile #");
11697                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11698                    }
11699                }
11700            }
11701        }
11702        if (mHomeProcess != null && (dumpPackage == null
11703                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11704            if (needSep) {
11705                pw.println();
11706                needSep = false;
11707            }
11708            pw.println("  mHomeProcess: " + mHomeProcess);
11709        }
11710        if (mPreviousProcess != null && (dumpPackage == null
11711                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11712            if (needSep) {
11713                pw.println();
11714                needSep = false;
11715            }
11716            pw.println("  mPreviousProcess: " + mPreviousProcess);
11717        }
11718        if (dumpAll) {
11719            StringBuilder sb = new StringBuilder(128);
11720            sb.append("  mPreviousProcessVisibleTime: ");
11721            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11722            pw.println(sb);
11723        }
11724        if (mHeavyWeightProcess != null && (dumpPackage == null
11725                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11726            if (needSep) {
11727                pw.println();
11728                needSep = false;
11729            }
11730            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11731        }
11732        if (dumpPackage == null) {
11733            pw.println("  mConfiguration: " + mConfiguration);
11734        }
11735        if (dumpAll) {
11736            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11737            if (mCompatModePackages.getPackages().size() > 0) {
11738                boolean printed = false;
11739                for (Map.Entry<String, Integer> entry
11740                        : mCompatModePackages.getPackages().entrySet()) {
11741                    String pkg = entry.getKey();
11742                    int mode = entry.getValue();
11743                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11744                        continue;
11745                    }
11746                    if (!printed) {
11747                        pw.println("  mScreenCompatPackages:");
11748                        printed = true;
11749                    }
11750                    pw.print("    "); pw.print(pkg); pw.print(": ");
11751                            pw.print(mode); pw.println();
11752                }
11753            }
11754        }
11755        if (dumpPackage == null) {
11756            if (mSleeping || mWentToSleep || mLockScreenShown) {
11757                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11758                        + " mLockScreenShown " + mLockScreenShown);
11759            }
11760            if (mShuttingDown || mRunningVoice) {
11761                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11762            }
11763        }
11764        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11765                || mOrigWaitForDebugger) {
11766            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11767                    || dumpPackage.equals(mOrigDebugApp)) {
11768                if (needSep) {
11769                    pw.println();
11770                    needSep = false;
11771                }
11772                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11773                        + " mDebugTransient=" + mDebugTransient
11774                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11775            }
11776        }
11777        if (mOpenGlTraceApp != null) {
11778            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11779                if (needSep) {
11780                    pw.println();
11781                    needSep = false;
11782                }
11783                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11784            }
11785        }
11786        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11787                || mProfileFd != null) {
11788            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11789                if (needSep) {
11790                    pw.println();
11791                    needSep = false;
11792                }
11793                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11794                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11795                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11796                        + mAutoStopProfiler);
11797            }
11798        }
11799        if (dumpPackage == null) {
11800            if (mAlwaysFinishActivities || mController != null) {
11801                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11802                        + " mController=" + mController);
11803            }
11804            if (dumpAll) {
11805                pw.println("  Total persistent processes: " + numPers);
11806                pw.println("  mProcessesReady=" + mProcessesReady
11807                        + " mSystemReady=" + mSystemReady);
11808                pw.println("  mBooting=" + mBooting
11809                        + " mBooted=" + mBooted
11810                        + " mFactoryTest=" + mFactoryTest);
11811                pw.print("  mLastPowerCheckRealtime=");
11812                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11813                        pw.println("");
11814                pw.print("  mLastPowerCheckUptime=");
11815                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11816                        pw.println("");
11817                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11818                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11819                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11820                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11821                        + " (" + mLruProcesses.size() + " total)"
11822                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11823                        + " mNumServiceProcs=" + mNumServiceProcs
11824                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11825                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11826                        + " mLastMemoryLevel" + mLastMemoryLevel
11827                        + " mLastNumProcesses" + mLastNumProcesses);
11828                long now = SystemClock.uptimeMillis();
11829                pw.print("  mLastIdleTime=");
11830                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11831                        pw.print(" mLowRamSinceLastIdle=");
11832                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11833                        pw.println();
11834            }
11835        }
11836
11837        if (!printedAnything) {
11838            pw.println("  (nothing)");
11839        }
11840    }
11841
11842    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11843            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11844        if (mProcessesToGc.size() > 0) {
11845            boolean printed = false;
11846            long now = SystemClock.uptimeMillis();
11847            for (int i=0; i<mProcessesToGc.size(); i++) {
11848                ProcessRecord proc = mProcessesToGc.get(i);
11849                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11850                    continue;
11851                }
11852                if (!printed) {
11853                    if (needSep) pw.println();
11854                    needSep = true;
11855                    pw.println("  Processes that are waiting to GC:");
11856                    printed = true;
11857                }
11858                pw.print("    Process "); pw.println(proc);
11859                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11860                        pw.print(", last gced=");
11861                        pw.print(now-proc.lastRequestedGc);
11862                        pw.print(" ms ago, last lowMem=");
11863                        pw.print(now-proc.lastLowMemory);
11864                        pw.println(" ms ago");
11865
11866            }
11867        }
11868        return needSep;
11869    }
11870
11871    void printOomLevel(PrintWriter pw, String name, int adj) {
11872        pw.print("    ");
11873        if (adj >= 0) {
11874            pw.print(' ');
11875            if (adj < 10) pw.print(' ');
11876        } else {
11877            if (adj > -10) pw.print(' ');
11878        }
11879        pw.print(adj);
11880        pw.print(": ");
11881        pw.print(name);
11882        pw.print(" (");
11883        pw.print(mProcessList.getMemLevel(adj)/1024);
11884        pw.println(" kB)");
11885    }
11886
11887    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11888            int opti, boolean dumpAll) {
11889        boolean needSep = false;
11890
11891        if (mLruProcesses.size() > 0) {
11892            if (needSep) pw.println();
11893            needSep = true;
11894            pw.println("  OOM levels:");
11895            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11896            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11897            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11898            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11899            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11900            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11901            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11902            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11903            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11904            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11905            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11906            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11907            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11908
11909            if (needSep) pw.println();
11910            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11911                    pw.print(" total, non-act at ");
11912                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11913                    pw.print(", non-svc at ");
11914                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11915                    pw.println("):");
11916            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11917            needSep = true;
11918        }
11919
11920        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11921
11922        pw.println();
11923        pw.println("  mHomeProcess: " + mHomeProcess);
11924        pw.println("  mPreviousProcess: " + mPreviousProcess);
11925        if (mHeavyWeightProcess != null) {
11926            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11927        }
11928
11929        return true;
11930    }
11931
11932    /**
11933     * There are three ways to call this:
11934     *  - no provider specified: dump all the providers
11935     *  - a flattened component name that matched an existing provider was specified as the
11936     *    first arg: dump that one provider
11937     *  - the first arg isn't the flattened component name of an existing provider:
11938     *    dump all providers whose component contains the first arg as a substring
11939     */
11940    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11941            int opti, boolean dumpAll) {
11942        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11943    }
11944
11945    static class ItemMatcher {
11946        ArrayList<ComponentName> components;
11947        ArrayList<String> strings;
11948        ArrayList<Integer> objects;
11949        boolean all;
11950
11951        ItemMatcher() {
11952            all = true;
11953        }
11954
11955        void build(String name) {
11956            ComponentName componentName = ComponentName.unflattenFromString(name);
11957            if (componentName != null) {
11958                if (components == null) {
11959                    components = new ArrayList<ComponentName>();
11960                }
11961                components.add(componentName);
11962                all = false;
11963            } else {
11964                int objectId = 0;
11965                // Not a '/' separated full component name; maybe an object ID?
11966                try {
11967                    objectId = Integer.parseInt(name, 16);
11968                    if (objects == null) {
11969                        objects = new ArrayList<Integer>();
11970                    }
11971                    objects.add(objectId);
11972                    all = false;
11973                } catch (RuntimeException e) {
11974                    // Not an integer; just do string match.
11975                    if (strings == null) {
11976                        strings = new ArrayList<String>();
11977                    }
11978                    strings.add(name);
11979                    all = false;
11980                }
11981            }
11982        }
11983
11984        int build(String[] args, int opti) {
11985            for (; opti<args.length; opti++) {
11986                String name = args[opti];
11987                if ("--".equals(name)) {
11988                    return opti+1;
11989                }
11990                build(name);
11991            }
11992            return opti;
11993        }
11994
11995        boolean match(Object object, ComponentName comp) {
11996            if (all) {
11997                return true;
11998            }
11999            if (components != null) {
12000                for (int i=0; i<components.size(); i++) {
12001                    if (components.get(i).equals(comp)) {
12002                        return true;
12003                    }
12004                }
12005            }
12006            if (objects != null) {
12007                for (int i=0; i<objects.size(); i++) {
12008                    if (System.identityHashCode(object) == objects.get(i)) {
12009                        return true;
12010                    }
12011                }
12012            }
12013            if (strings != null) {
12014                String flat = comp.flattenToString();
12015                for (int i=0; i<strings.size(); i++) {
12016                    if (flat.contains(strings.get(i))) {
12017                        return true;
12018                    }
12019                }
12020            }
12021            return false;
12022        }
12023    }
12024
12025    /**
12026     * There are three things that cmd can be:
12027     *  - a flattened component name that matches an existing activity
12028     *  - the cmd arg isn't the flattened component name of an existing activity:
12029     *    dump all activity whose component contains the cmd as a substring
12030     *  - A hex number of the ActivityRecord object instance.
12031     */
12032    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12033            int opti, boolean dumpAll) {
12034        ArrayList<ActivityRecord> activities;
12035
12036        synchronized (this) {
12037            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12038        }
12039
12040        if (activities.size() <= 0) {
12041            return false;
12042        }
12043
12044        String[] newArgs = new String[args.length - opti];
12045        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12046
12047        TaskRecord lastTask = null;
12048        boolean needSep = false;
12049        for (int i=activities.size()-1; i>=0; i--) {
12050            ActivityRecord r = activities.get(i);
12051            if (needSep) {
12052                pw.println();
12053            }
12054            needSep = true;
12055            synchronized (this) {
12056                if (lastTask != r.task) {
12057                    lastTask = r.task;
12058                    pw.print("TASK "); pw.print(lastTask.affinity);
12059                            pw.print(" id="); pw.println(lastTask.taskId);
12060                    if (dumpAll) {
12061                        lastTask.dump(pw, "  ");
12062                    }
12063                }
12064            }
12065            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12066        }
12067        return true;
12068    }
12069
12070    /**
12071     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12072     * there is a thread associated with the activity.
12073     */
12074    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12075            final ActivityRecord r, String[] args, boolean dumpAll) {
12076        String innerPrefix = prefix + "  ";
12077        synchronized (this) {
12078            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12079                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12080                    pw.print(" pid=");
12081                    if (r.app != null) pw.println(r.app.pid);
12082                    else pw.println("(not running)");
12083            if (dumpAll) {
12084                r.dump(pw, innerPrefix);
12085            }
12086        }
12087        if (r.app != null && r.app.thread != null) {
12088            // flush anything that is already in the PrintWriter since the thread is going
12089            // to write to the file descriptor directly
12090            pw.flush();
12091            try {
12092                TransferPipe tp = new TransferPipe();
12093                try {
12094                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12095                            r.appToken, innerPrefix, args);
12096                    tp.go(fd);
12097                } finally {
12098                    tp.kill();
12099                }
12100            } catch (IOException e) {
12101                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12102            } catch (RemoteException e) {
12103                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12104            }
12105        }
12106    }
12107
12108    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12109            int opti, boolean dumpAll, String dumpPackage) {
12110        boolean needSep = false;
12111        boolean onlyHistory = false;
12112        boolean printedAnything = false;
12113
12114        if ("history".equals(dumpPackage)) {
12115            if (opti < args.length && "-s".equals(args[opti])) {
12116                dumpAll = false;
12117            }
12118            onlyHistory = true;
12119            dumpPackage = null;
12120        }
12121
12122        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12123        if (!onlyHistory && dumpAll) {
12124            if (mRegisteredReceivers.size() > 0) {
12125                boolean printed = false;
12126                Iterator it = mRegisteredReceivers.values().iterator();
12127                while (it.hasNext()) {
12128                    ReceiverList r = (ReceiverList)it.next();
12129                    if (dumpPackage != null && (r.app == null ||
12130                            !dumpPackage.equals(r.app.info.packageName))) {
12131                        continue;
12132                    }
12133                    if (!printed) {
12134                        pw.println("  Registered Receivers:");
12135                        needSep = true;
12136                        printed = true;
12137                        printedAnything = true;
12138                    }
12139                    pw.print("  * "); pw.println(r);
12140                    r.dump(pw, "    ");
12141                }
12142            }
12143
12144            if (mReceiverResolver.dump(pw, needSep ?
12145                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12146                    "    ", dumpPackage, false)) {
12147                needSep = true;
12148                printedAnything = true;
12149            }
12150        }
12151
12152        for (BroadcastQueue q : mBroadcastQueues) {
12153            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12154            printedAnything |= needSep;
12155        }
12156
12157        needSep = true;
12158
12159        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12160            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12161                if (needSep) {
12162                    pw.println();
12163                }
12164                needSep = true;
12165                printedAnything = true;
12166                pw.print("  Sticky broadcasts for user ");
12167                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12168                StringBuilder sb = new StringBuilder(128);
12169                for (Map.Entry<String, ArrayList<Intent>> ent
12170                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12171                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12172                    if (dumpAll) {
12173                        pw.println(":");
12174                        ArrayList<Intent> intents = ent.getValue();
12175                        final int N = intents.size();
12176                        for (int i=0; i<N; i++) {
12177                            sb.setLength(0);
12178                            sb.append("    Intent: ");
12179                            intents.get(i).toShortString(sb, false, true, false, false);
12180                            pw.println(sb.toString());
12181                            Bundle bundle = intents.get(i).getExtras();
12182                            if (bundle != null) {
12183                                pw.print("      ");
12184                                pw.println(bundle.toString());
12185                            }
12186                        }
12187                    } else {
12188                        pw.println("");
12189                    }
12190                }
12191            }
12192        }
12193
12194        if (!onlyHistory && dumpAll) {
12195            pw.println();
12196            for (BroadcastQueue queue : mBroadcastQueues) {
12197                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12198                        + queue.mBroadcastsScheduled);
12199            }
12200            pw.println("  mHandler:");
12201            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12202            needSep = true;
12203            printedAnything = true;
12204        }
12205
12206        if (!printedAnything) {
12207            pw.println("  (nothing)");
12208        }
12209    }
12210
12211    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12212            int opti, boolean dumpAll, String dumpPackage) {
12213        boolean needSep;
12214        boolean printedAnything = false;
12215
12216        ItemMatcher matcher = new ItemMatcher();
12217        matcher.build(args, opti);
12218
12219        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12220
12221        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12222        printedAnything |= needSep;
12223
12224        if (mLaunchingProviders.size() > 0) {
12225            boolean printed = false;
12226            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12227                ContentProviderRecord r = mLaunchingProviders.get(i);
12228                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12229                    continue;
12230                }
12231                if (!printed) {
12232                    if (needSep) pw.println();
12233                    needSep = true;
12234                    pw.println("  Launching content providers:");
12235                    printed = true;
12236                    printedAnything = true;
12237                }
12238                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12239                        pw.println(r);
12240            }
12241        }
12242
12243        if (mGrantedUriPermissions.size() > 0) {
12244            boolean printed = false;
12245            int dumpUid = -2;
12246            if (dumpPackage != null) {
12247                try {
12248                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12249                } catch (NameNotFoundException e) {
12250                    dumpUid = -1;
12251                }
12252            }
12253            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12254                int uid = mGrantedUriPermissions.keyAt(i);
12255                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12256                    continue;
12257                }
12258                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12259                if (!printed) {
12260                    if (needSep) pw.println();
12261                    needSep = true;
12262                    pw.println("  Granted Uri Permissions:");
12263                    printed = true;
12264                    printedAnything = true;
12265                }
12266                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12267                for (UriPermission perm : perms.values()) {
12268                    pw.print("    "); pw.println(perm);
12269                    if (dumpAll) {
12270                        perm.dump(pw, "      ");
12271                    }
12272                }
12273            }
12274        }
12275
12276        if (!printedAnything) {
12277            pw.println("  (nothing)");
12278        }
12279    }
12280
12281    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12282            int opti, boolean dumpAll, String dumpPackage) {
12283        boolean printed = false;
12284
12285        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12286
12287        if (mIntentSenderRecords.size() > 0) {
12288            Iterator<WeakReference<PendingIntentRecord>> it
12289                    = mIntentSenderRecords.values().iterator();
12290            while (it.hasNext()) {
12291                WeakReference<PendingIntentRecord> ref = it.next();
12292                PendingIntentRecord rec = ref != null ? ref.get(): null;
12293                if (dumpPackage != null && (rec == null
12294                        || !dumpPackage.equals(rec.key.packageName))) {
12295                    continue;
12296                }
12297                printed = true;
12298                if (rec != null) {
12299                    pw.print("  * "); pw.println(rec);
12300                    if (dumpAll) {
12301                        rec.dump(pw, "    ");
12302                    }
12303                } else {
12304                    pw.print("  * "); pw.println(ref);
12305                }
12306            }
12307        }
12308
12309        if (!printed) {
12310            pw.println("  (nothing)");
12311        }
12312    }
12313
12314    private static final int dumpProcessList(PrintWriter pw,
12315            ActivityManagerService service, List list,
12316            String prefix, String normalLabel, String persistentLabel,
12317            String dumpPackage) {
12318        int numPers = 0;
12319        final int N = list.size()-1;
12320        for (int i=N; i>=0; i--) {
12321            ProcessRecord r = (ProcessRecord)list.get(i);
12322            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12323                continue;
12324            }
12325            pw.println(String.format("%s%s #%2d: %s",
12326                    prefix, (r.persistent ? persistentLabel : normalLabel),
12327                    i, r.toString()));
12328            if (r.persistent) {
12329                numPers++;
12330            }
12331        }
12332        return numPers;
12333    }
12334
12335    private static final boolean dumpProcessOomList(PrintWriter pw,
12336            ActivityManagerService service, List<ProcessRecord> origList,
12337            String prefix, String normalLabel, String persistentLabel,
12338            boolean inclDetails, String dumpPackage) {
12339
12340        ArrayList<Pair<ProcessRecord, Integer>> list
12341                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12342        for (int i=0; i<origList.size(); i++) {
12343            ProcessRecord r = origList.get(i);
12344            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12345                continue;
12346            }
12347            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12348        }
12349
12350        if (list.size() <= 0) {
12351            return false;
12352        }
12353
12354        Comparator<Pair<ProcessRecord, Integer>> comparator
12355                = new Comparator<Pair<ProcessRecord, Integer>>() {
12356            @Override
12357            public int compare(Pair<ProcessRecord, Integer> object1,
12358                    Pair<ProcessRecord, Integer> object2) {
12359                if (object1.first.setAdj != object2.first.setAdj) {
12360                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12361                }
12362                if (object1.second.intValue() != object2.second.intValue()) {
12363                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12364                }
12365                return 0;
12366            }
12367        };
12368
12369        Collections.sort(list, comparator);
12370
12371        final long curRealtime = SystemClock.elapsedRealtime();
12372        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12373        final long curUptime = SystemClock.uptimeMillis();
12374        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12375
12376        for (int i=list.size()-1; i>=0; i--) {
12377            ProcessRecord r = list.get(i).first;
12378            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12379            char schedGroup;
12380            switch (r.setSchedGroup) {
12381                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12382                    schedGroup = 'B';
12383                    break;
12384                case Process.THREAD_GROUP_DEFAULT:
12385                    schedGroup = 'F';
12386                    break;
12387                default:
12388                    schedGroup = '?';
12389                    break;
12390            }
12391            char foreground;
12392            if (r.foregroundActivities) {
12393                foreground = 'A';
12394            } else if (r.foregroundServices) {
12395                foreground = 'S';
12396            } else {
12397                foreground = ' ';
12398            }
12399            String procState = ProcessList.makeProcStateString(r.curProcState);
12400            pw.print(prefix);
12401            pw.print(r.persistent ? persistentLabel : normalLabel);
12402            pw.print(" #");
12403            int num = (origList.size()-1)-list.get(i).second;
12404            if (num < 10) pw.print(' ');
12405            pw.print(num);
12406            pw.print(": ");
12407            pw.print(oomAdj);
12408            pw.print(' ');
12409            pw.print(schedGroup);
12410            pw.print('/');
12411            pw.print(foreground);
12412            pw.print('/');
12413            pw.print(procState);
12414            pw.print(" trm:");
12415            if (r.trimMemoryLevel < 10) pw.print(' ');
12416            pw.print(r.trimMemoryLevel);
12417            pw.print(' ');
12418            pw.print(r.toShortString());
12419            pw.print(" (");
12420            pw.print(r.adjType);
12421            pw.println(')');
12422            if (r.adjSource != null || r.adjTarget != null) {
12423                pw.print(prefix);
12424                pw.print("    ");
12425                if (r.adjTarget instanceof ComponentName) {
12426                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12427                } else if (r.adjTarget != null) {
12428                    pw.print(r.adjTarget.toString());
12429                } else {
12430                    pw.print("{null}");
12431                }
12432                pw.print("<=");
12433                if (r.adjSource instanceof ProcessRecord) {
12434                    pw.print("Proc{");
12435                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12436                    pw.println("}");
12437                } else if (r.adjSource != null) {
12438                    pw.println(r.adjSource.toString());
12439                } else {
12440                    pw.println("{null}");
12441                }
12442            }
12443            if (inclDetails) {
12444                pw.print(prefix);
12445                pw.print("    ");
12446                pw.print("oom: max="); pw.print(r.maxAdj);
12447                pw.print(" curRaw="); pw.print(r.curRawAdj);
12448                pw.print(" setRaw="); pw.print(r.setRawAdj);
12449                pw.print(" cur="); pw.print(r.curAdj);
12450                pw.print(" set="); pw.println(r.setAdj);
12451                pw.print(prefix);
12452                pw.print("    ");
12453                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12454                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12455                pw.print(" lastPss="); pw.print(r.lastPss);
12456                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12457                pw.print(prefix);
12458                pw.print("    ");
12459                pw.print("cached="); pw.print(r.cached);
12460                pw.print(" empty="); pw.print(r.empty);
12461                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12462
12463                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12464                    if (r.lastWakeTime != 0) {
12465                        long wtime;
12466                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12467                        synchronized (stats) {
12468                            wtime = stats.getProcessWakeTime(r.info.uid,
12469                                    r.pid, curRealtime);
12470                        }
12471                        long timeUsed = wtime - r.lastWakeTime;
12472                        pw.print(prefix);
12473                        pw.print("    ");
12474                        pw.print("keep awake over ");
12475                        TimeUtils.formatDuration(realtimeSince, pw);
12476                        pw.print(" used ");
12477                        TimeUtils.formatDuration(timeUsed, pw);
12478                        pw.print(" (");
12479                        pw.print((timeUsed*100)/realtimeSince);
12480                        pw.println("%)");
12481                    }
12482                    if (r.lastCpuTime != 0) {
12483                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12484                        pw.print(prefix);
12485                        pw.print("    ");
12486                        pw.print("run cpu over ");
12487                        TimeUtils.formatDuration(uptimeSince, pw);
12488                        pw.print(" used ");
12489                        TimeUtils.formatDuration(timeUsed, pw);
12490                        pw.print(" (");
12491                        pw.print((timeUsed*100)/uptimeSince);
12492                        pw.println("%)");
12493                    }
12494                }
12495            }
12496        }
12497        return true;
12498    }
12499
12500    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12501        ArrayList<ProcessRecord> procs;
12502        synchronized (this) {
12503            if (args != null && args.length > start
12504                    && args[start].charAt(0) != '-') {
12505                procs = new ArrayList<ProcessRecord>();
12506                int pid = -1;
12507                try {
12508                    pid = Integer.parseInt(args[start]);
12509                } catch (NumberFormatException e) {
12510                }
12511                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12512                    ProcessRecord proc = mLruProcesses.get(i);
12513                    if (proc.pid == pid) {
12514                        procs.add(proc);
12515                    } else if (proc.processName.equals(args[start])) {
12516                        procs.add(proc);
12517                    }
12518                }
12519                if (procs.size() <= 0) {
12520                    return null;
12521                }
12522            } else {
12523                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12524            }
12525        }
12526        return procs;
12527    }
12528
12529    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12530            PrintWriter pw, String[] args) {
12531        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12532        if (procs == null) {
12533            pw.println("No process found for: " + args[0]);
12534            return;
12535        }
12536
12537        long uptime = SystemClock.uptimeMillis();
12538        long realtime = SystemClock.elapsedRealtime();
12539        pw.println("Applications Graphics Acceleration Info:");
12540        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12541
12542        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12543            ProcessRecord r = procs.get(i);
12544            if (r.thread != null) {
12545                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12546                pw.flush();
12547                try {
12548                    TransferPipe tp = new TransferPipe();
12549                    try {
12550                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12551                        tp.go(fd);
12552                    } finally {
12553                        tp.kill();
12554                    }
12555                } catch (IOException e) {
12556                    pw.println("Failure while dumping the app: " + r);
12557                    pw.flush();
12558                } catch (RemoteException e) {
12559                    pw.println("Got a RemoteException while dumping the app " + r);
12560                    pw.flush();
12561                }
12562            }
12563        }
12564    }
12565
12566    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12567        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12568        if (procs == null) {
12569            pw.println("No process found for: " + args[0]);
12570            return;
12571        }
12572
12573        pw.println("Applications Database Info:");
12574
12575        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12576            ProcessRecord r = procs.get(i);
12577            if (r.thread != null) {
12578                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12579                pw.flush();
12580                try {
12581                    TransferPipe tp = new TransferPipe();
12582                    try {
12583                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12584                        tp.go(fd);
12585                    } finally {
12586                        tp.kill();
12587                    }
12588                } catch (IOException e) {
12589                    pw.println("Failure while dumping the app: " + r);
12590                    pw.flush();
12591                } catch (RemoteException e) {
12592                    pw.println("Got a RemoteException while dumping the app " + r);
12593                    pw.flush();
12594                }
12595            }
12596        }
12597    }
12598
12599    final static class MemItem {
12600        final boolean isProc;
12601        final String label;
12602        final String shortLabel;
12603        final long pss;
12604        final int id;
12605        final boolean hasActivities;
12606        ArrayList<MemItem> subitems;
12607
12608        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12609                boolean _hasActivities) {
12610            isProc = true;
12611            label = _label;
12612            shortLabel = _shortLabel;
12613            pss = _pss;
12614            id = _id;
12615            hasActivities = _hasActivities;
12616        }
12617
12618        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12619            isProc = false;
12620            label = _label;
12621            shortLabel = _shortLabel;
12622            pss = _pss;
12623            id = _id;
12624            hasActivities = false;
12625        }
12626    }
12627
12628    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12629            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12630        if (sort && !isCompact) {
12631            Collections.sort(items, new Comparator<MemItem>() {
12632                @Override
12633                public int compare(MemItem lhs, MemItem rhs) {
12634                    if (lhs.pss < rhs.pss) {
12635                        return 1;
12636                    } else if (lhs.pss > rhs.pss) {
12637                        return -1;
12638                    }
12639                    return 0;
12640                }
12641            });
12642        }
12643
12644        for (int i=0; i<items.size(); i++) {
12645            MemItem mi = items.get(i);
12646            if (!isCompact) {
12647                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12648            } else if (mi.isProc) {
12649                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12650                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12651                pw.println(mi.hasActivities ? ",a" : ",e");
12652            } else {
12653                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12654                pw.println(mi.pss);
12655            }
12656            if (mi.subitems != null) {
12657                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12658                        true, isCompact);
12659            }
12660        }
12661    }
12662
12663    // These are in KB.
12664    static final long[] DUMP_MEM_BUCKETS = new long[] {
12665        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12666        120*1024, 160*1024, 200*1024,
12667        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12668        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12669    };
12670
12671    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12672            boolean stackLike) {
12673        int start = label.lastIndexOf('.');
12674        if (start >= 0) start++;
12675        else start = 0;
12676        int end = label.length();
12677        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12678            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12679                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12680                out.append(bucket);
12681                out.append(stackLike ? "MB." : "MB ");
12682                out.append(label, start, end);
12683                return;
12684            }
12685        }
12686        out.append(memKB/1024);
12687        out.append(stackLike ? "MB." : "MB ");
12688        out.append(label, start, end);
12689    }
12690
12691    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12692            ProcessList.NATIVE_ADJ,
12693            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12694            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12695            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12696            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12697            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12698    };
12699    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12700            "Native",
12701            "System", "Persistent", "Foreground",
12702            "Visible", "Perceptible",
12703            "Heavy Weight", "Backup",
12704            "A Services", "Home",
12705            "Previous", "B Services", "Cached"
12706    };
12707    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12708            "native",
12709            "sys", "pers", "fore",
12710            "vis", "percept",
12711            "heavy", "backup",
12712            "servicea", "home",
12713            "prev", "serviceb", "cached"
12714    };
12715
12716    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12717            long realtime, boolean isCheckinRequest, boolean isCompact) {
12718        if (isCheckinRequest || isCompact) {
12719            // short checkin version
12720            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12721        } else {
12722            pw.println("Applications Memory Usage (kB):");
12723            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12724        }
12725    }
12726
12727    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12728            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12729        boolean dumpDetails = false;
12730        boolean dumpFullDetails = false;
12731        boolean dumpDalvik = false;
12732        boolean oomOnly = false;
12733        boolean isCompact = false;
12734        boolean localOnly = false;
12735
12736        int opti = 0;
12737        while (opti < args.length) {
12738            String opt = args[opti];
12739            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12740                break;
12741            }
12742            opti++;
12743            if ("-a".equals(opt)) {
12744                dumpDetails = true;
12745                dumpFullDetails = true;
12746                dumpDalvik = true;
12747            } else if ("-d".equals(opt)) {
12748                dumpDalvik = true;
12749            } else if ("-c".equals(opt)) {
12750                isCompact = true;
12751            } else if ("--oom".equals(opt)) {
12752                oomOnly = true;
12753            } else if ("--local".equals(opt)) {
12754                localOnly = true;
12755            } else if ("-h".equals(opt)) {
12756                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12757                pw.println("  -a: include all available information for each process.");
12758                pw.println("  -d: include dalvik details when dumping process details.");
12759                pw.println("  -c: dump in a compact machine-parseable representation.");
12760                pw.println("  --oom: only show processes organized by oom adj.");
12761                pw.println("  --local: only collect details locally, don't call process.");
12762                pw.println("If [process] is specified it can be the name or ");
12763                pw.println("pid of a specific process to dump.");
12764                return;
12765            } else {
12766                pw.println("Unknown argument: " + opt + "; use -h for help");
12767            }
12768        }
12769
12770        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12771        long uptime = SystemClock.uptimeMillis();
12772        long realtime = SystemClock.elapsedRealtime();
12773        final long[] tmpLong = new long[1];
12774
12775        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12776        if (procs == null) {
12777            // No Java processes.  Maybe they want to print a native process.
12778            if (args != null && args.length > opti
12779                    && args[opti].charAt(0) != '-') {
12780                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12781                        = new ArrayList<ProcessCpuTracker.Stats>();
12782                updateCpuStatsNow();
12783                int findPid = -1;
12784                try {
12785                    findPid = Integer.parseInt(args[opti]);
12786                } catch (NumberFormatException e) {
12787                }
12788                synchronized (mProcessCpuThread) {
12789                    final int N = mProcessCpuTracker.countStats();
12790                    for (int i=0; i<N; i++) {
12791                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12792                        if (st.pid == findPid || (st.baseName != null
12793                                && st.baseName.equals(args[opti]))) {
12794                            nativeProcs.add(st);
12795                        }
12796                    }
12797                }
12798                if (nativeProcs.size() > 0) {
12799                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12800                            isCompact);
12801                    Debug.MemoryInfo mi = null;
12802                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12803                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12804                        final int pid = r.pid;
12805                        if (!isCheckinRequest && dumpDetails) {
12806                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12807                        }
12808                        if (mi == null) {
12809                            mi = new Debug.MemoryInfo();
12810                        }
12811                        if (dumpDetails || (!brief && !oomOnly)) {
12812                            Debug.getMemoryInfo(pid, mi);
12813                        } else {
12814                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12815                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12816                        }
12817                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12818                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12819                        if (isCheckinRequest) {
12820                            pw.println();
12821                        }
12822                    }
12823                    return;
12824                }
12825            }
12826            pw.println("No process found for: " + args[opti]);
12827            return;
12828        }
12829
12830        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12831            dumpDetails = true;
12832        }
12833
12834        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12835
12836        String[] innerArgs = new String[args.length-opti];
12837        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12838
12839        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12840        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12841        long nativePss=0, dalvikPss=0, otherPss=0;
12842        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12843
12844        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12845        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12846                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12847
12848        long totalPss = 0;
12849        long cachedPss = 0;
12850
12851        Debug.MemoryInfo mi = null;
12852        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12853            final ProcessRecord r = procs.get(i);
12854            final IApplicationThread thread;
12855            final int pid;
12856            final int oomAdj;
12857            final boolean hasActivities;
12858            synchronized (this) {
12859                thread = r.thread;
12860                pid = r.pid;
12861                oomAdj = r.getSetAdjWithServices();
12862                hasActivities = r.activities.size() > 0;
12863            }
12864            if (thread != null) {
12865                if (!isCheckinRequest && dumpDetails) {
12866                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12867                }
12868                if (mi == null) {
12869                    mi = new Debug.MemoryInfo();
12870                }
12871                if (dumpDetails || (!brief && !oomOnly)) {
12872                    Debug.getMemoryInfo(pid, mi);
12873                } else {
12874                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12875                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12876                }
12877                if (dumpDetails) {
12878                    if (localOnly) {
12879                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12880                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12881                        if (isCheckinRequest) {
12882                            pw.println();
12883                        }
12884                    } else {
12885                        try {
12886                            pw.flush();
12887                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12888                                    dumpDalvik, innerArgs);
12889                        } catch (RemoteException e) {
12890                            if (!isCheckinRequest) {
12891                                pw.println("Got RemoteException!");
12892                                pw.flush();
12893                            }
12894                        }
12895                    }
12896                }
12897
12898                final long myTotalPss = mi.getTotalPss();
12899                final long myTotalUss = mi.getTotalUss();
12900
12901                synchronized (this) {
12902                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12903                        // Record this for posterity if the process has been stable.
12904                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12905                    }
12906                }
12907
12908                if (!isCheckinRequest && mi != null) {
12909                    totalPss += myTotalPss;
12910                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12911                            (hasActivities ? " / activities)" : ")"),
12912                            r.processName, myTotalPss, pid, hasActivities);
12913                    procMems.add(pssItem);
12914                    procMemsMap.put(pid, pssItem);
12915
12916                    nativePss += mi.nativePss;
12917                    dalvikPss += mi.dalvikPss;
12918                    otherPss += mi.otherPss;
12919                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12920                        long mem = mi.getOtherPss(j);
12921                        miscPss[j] += mem;
12922                        otherPss -= mem;
12923                    }
12924
12925                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12926                        cachedPss += myTotalPss;
12927                    }
12928
12929                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12930                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12931                                || oomIndex == (oomPss.length-1)) {
12932                            oomPss[oomIndex] += myTotalPss;
12933                            if (oomProcs[oomIndex] == null) {
12934                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12935                            }
12936                            oomProcs[oomIndex].add(pssItem);
12937                            break;
12938                        }
12939                    }
12940                }
12941            }
12942        }
12943
12944        long nativeProcTotalPss = 0;
12945
12946        if (!isCheckinRequest && procs.size() > 1) {
12947            // If we are showing aggregations, also look for native processes to
12948            // include so that our aggregations are more accurate.
12949            updateCpuStatsNow();
12950            synchronized (mProcessCpuThread) {
12951                final int N = mProcessCpuTracker.countStats();
12952                for (int i=0; i<N; i++) {
12953                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12954                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12955                        if (mi == null) {
12956                            mi = new Debug.MemoryInfo();
12957                        }
12958                        if (!brief && !oomOnly) {
12959                            Debug.getMemoryInfo(st.pid, mi);
12960                        } else {
12961                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12962                            mi.nativePrivateDirty = (int)tmpLong[0];
12963                        }
12964
12965                        final long myTotalPss = mi.getTotalPss();
12966                        totalPss += myTotalPss;
12967                        nativeProcTotalPss += myTotalPss;
12968
12969                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12970                                st.name, myTotalPss, st.pid, false);
12971                        procMems.add(pssItem);
12972
12973                        nativePss += mi.nativePss;
12974                        dalvikPss += mi.dalvikPss;
12975                        otherPss += mi.otherPss;
12976                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12977                            long mem = mi.getOtherPss(j);
12978                            miscPss[j] += mem;
12979                            otherPss -= mem;
12980                        }
12981                        oomPss[0] += myTotalPss;
12982                        if (oomProcs[0] == null) {
12983                            oomProcs[0] = new ArrayList<MemItem>();
12984                        }
12985                        oomProcs[0].add(pssItem);
12986                    }
12987                }
12988            }
12989
12990            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12991
12992            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12993            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12994            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12995            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12996                String label = Debug.MemoryInfo.getOtherLabel(j);
12997                catMems.add(new MemItem(label, label, miscPss[j], j));
12998            }
12999
13000            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13001            for (int j=0; j<oomPss.length; j++) {
13002                if (oomPss[j] != 0) {
13003                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13004                            : DUMP_MEM_OOM_LABEL[j];
13005                    MemItem item = new MemItem(label, label, oomPss[j],
13006                            DUMP_MEM_OOM_ADJ[j]);
13007                    item.subitems = oomProcs[j];
13008                    oomMems.add(item);
13009                }
13010            }
13011
13012            if (!brief && !oomOnly && !isCompact) {
13013                pw.println();
13014                pw.println("Total PSS by process:");
13015                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13016                pw.println();
13017            }
13018            if (!isCompact) {
13019                pw.println("Total PSS by OOM adjustment:");
13020            }
13021            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13022            if (!brief && !oomOnly) {
13023                PrintWriter out = categoryPw != null ? categoryPw : pw;
13024                if (!isCompact) {
13025                    out.println();
13026                    out.println("Total PSS by category:");
13027                }
13028                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13029            }
13030            if (!isCompact) {
13031                pw.println();
13032            }
13033            MemInfoReader memInfo = new MemInfoReader();
13034            memInfo.readMemInfo();
13035            if (nativeProcTotalPss > 0) {
13036                synchronized (this) {
13037                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13038                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13039                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13040                            nativeProcTotalPss);
13041                }
13042            }
13043            if (!brief) {
13044                if (!isCompact) {
13045                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13046                    pw.print(" kB (status ");
13047                    switch (mLastMemoryLevel) {
13048                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13049                            pw.println("normal)");
13050                            break;
13051                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13052                            pw.println("moderate)");
13053                            break;
13054                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13055                            pw.println("low)");
13056                            break;
13057                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13058                            pw.println("critical)");
13059                            break;
13060                        default:
13061                            pw.print(mLastMemoryLevel);
13062                            pw.println(")");
13063                            break;
13064                    }
13065                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13066                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13067                            pw.print(cachedPss); pw.print(" cached pss + ");
13068                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13069                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13070                } else {
13071                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13072                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13073                            + memInfo.getFreeSizeKb()); pw.print(",");
13074                    pw.println(totalPss - cachedPss);
13075                }
13076            }
13077            if (!isCompact) {
13078                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13079                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13080                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13081                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13082                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13083                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13084                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13085                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13086                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13087                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13088                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13089            }
13090            if (!brief) {
13091                if (memInfo.getZramTotalSizeKb() != 0) {
13092                    if (!isCompact) {
13093                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13094                                pw.print(" kB physical used for ");
13095                                pw.print(memInfo.getSwapTotalSizeKb()
13096                                        - memInfo.getSwapFreeSizeKb());
13097                                pw.print(" kB in swap (");
13098                                pw.print(memInfo.getSwapTotalSizeKb());
13099                                pw.println(" kB total swap)");
13100                    } else {
13101                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13102                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13103                                pw.println(memInfo.getSwapFreeSizeKb());
13104                    }
13105                }
13106                final int[] SINGLE_LONG_FORMAT = new int[] {
13107                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13108                };
13109                long[] longOut = new long[1];
13110                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13111                        SINGLE_LONG_FORMAT, null, longOut, null);
13112                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13113                longOut[0] = 0;
13114                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13115                        SINGLE_LONG_FORMAT, null, longOut, null);
13116                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13117                longOut[0] = 0;
13118                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13119                        SINGLE_LONG_FORMAT, null, longOut, null);
13120                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13121                longOut[0] = 0;
13122                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13123                        SINGLE_LONG_FORMAT, null, longOut, null);
13124                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13125                if (!isCompact) {
13126                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13127                        pw.print("      KSM: "); pw.print(sharing);
13128                                pw.print(" kB saved from shared ");
13129                                pw.print(shared); pw.println(" kB");
13130                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13131                                pw.print(voltile); pw.println(" kB volatile");
13132                    }
13133                    pw.print("   Tuning: ");
13134                    pw.print(ActivityManager.staticGetMemoryClass());
13135                    pw.print(" (large ");
13136                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13137                    pw.print("), oom ");
13138                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13139                    pw.print(" kB");
13140                    pw.print(", restore limit ");
13141                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13142                    pw.print(" kB");
13143                    if (ActivityManager.isLowRamDeviceStatic()) {
13144                        pw.print(" (low-ram)");
13145                    }
13146                    if (ActivityManager.isHighEndGfx()) {
13147                        pw.print(" (high-end-gfx)");
13148                    }
13149                    pw.println();
13150                } else {
13151                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13152                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13153                    pw.println(voltile);
13154                    pw.print("tuning,");
13155                    pw.print(ActivityManager.staticGetMemoryClass());
13156                    pw.print(',');
13157                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13158                    pw.print(',');
13159                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13160                    if (ActivityManager.isLowRamDeviceStatic()) {
13161                        pw.print(",low-ram");
13162                    }
13163                    if (ActivityManager.isHighEndGfx()) {
13164                        pw.print(",high-end-gfx");
13165                    }
13166                    pw.println();
13167                }
13168            }
13169        }
13170    }
13171
13172    /**
13173     * Searches array of arguments for the specified string
13174     * @param args array of argument strings
13175     * @param value value to search for
13176     * @return true if the value is contained in the array
13177     */
13178    private static boolean scanArgs(String[] args, String value) {
13179        if (args != null) {
13180            for (String arg : args) {
13181                if (value.equals(arg)) {
13182                    return true;
13183                }
13184            }
13185        }
13186        return false;
13187    }
13188
13189    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13190            ContentProviderRecord cpr, boolean always) {
13191        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13192
13193        if (!inLaunching || always) {
13194            synchronized (cpr) {
13195                cpr.launchingApp = null;
13196                cpr.notifyAll();
13197            }
13198            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13199            String names[] = cpr.info.authority.split(";");
13200            for (int j = 0; j < names.length; j++) {
13201                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13202            }
13203        }
13204
13205        for (int i=0; i<cpr.connections.size(); i++) {
13206            ContentProviderConnection conn = cpr.connections.get(i);
13207            if (conn.waiting) {
13208                // If this connection is waiting for the provider, then we don't
13209                // need to mess with its process unless we are always removing
13210                // or for some reason the provider is not currently launching.
13211                if (inLaunching && !always) {
13212                    continue;
13213                }
13214            }
13215            ProcessRecord capp = conn.client;
13216            conn.dead = true;
13217            if (conn.stableCount > 0) {
13218                if (!capp.persistent && capp.thread != null
13219                        && capp.pid != 0
13220                        && capp.pid != MY_PID) {
13221                    killUnneededProcessLocked(capp, "depends on provider "
13222                            + cpr.name.flattenToShortString()
13223                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13224                }
13225            } else if (capp.thread != null && conn.provider.provider != null) {
13226                try {
13227                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13228                } catch (RemoteException e) {
13229                }
13230                // In the protocol here, we don't expect the client to correctly
13231                // clean up this connection, we'll just remove it.
13232                cpr.connections.remove(i);
13233                conn.client.conProviders.remove(conn);
13234            }
13235        }
13236
13237        if (inLaunching && always) {
13238            mLaunchingProviders.remove(cpr);
13239        }
13240        return inLaunching;
13241    }
13242
13243    /**
13244     * Main code for cleaning up a process when it has gone away.  This is
13245     * called both as a result of the process dying, or directly when stopping
13246     * a process when running in single process mode.
13247     */
13248    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13249            boolean restarting, boolean allowRestart, int index) {
13250        if (index >= 0) {
13251            removeLruProcessLocked(app);
13252            ProcessList.remove(app.pid);
13253        }
13254
13255        mProcessesToGc.remove(app);
13256        mPendingPssProcesses.remove(app);
13257
13258        // Dismiss any open dialogs.
13259        if (app.crashDialog != null && !app.forceCrashReport) {
13260            app.crashDialog.dismiss();
13261            app.crashDialog = null;
13262        }
13263        if (app.anrDialog != null) {
13264            app.anrDialog.dismiss();
13265            app.anrDialog = null;
13266        }
13267        if (app.waitDialog != null) {
13268            app.waitDialog.dismiss();
13269            app.waitDialog = null;
13270        }
13271
13272        app.crashing = false;
13273        app.notResponding = false;
13274
13275        app.resetPackageList(mProcessStats);
13276        app.unlinkDeathRecipient();
13277        app.makeInactive(mProcessStats);
13278        app.waitingToKill = null;
13279        app.forcingToForeground = null;
13280        updateProcessForegroundLocked(app, false, false);
13281        app.foregroundActivities = false;
13282        app.hasShownUi = false;
13283        app.treatLikeActivity = false;
13284        app.hasAboveClient = false;
13285        app.hasClientActivities = false;
13286
13287        mServices.killServicesLocked(app, allowRestart);
13288
13289        boolean restart = false;
13290
13291        // Remove published content providers.
13292        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13293            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13294            final boolean always = app.bad || !allowRestart;
13295            if (removeDyingProviderLocked(app, cpr, always) || always) {
13296                // We left the provider in the launching list, need to
13297                // restart it.
13298                restart = true;
13299            }
13300
13301            cpr.provider = null;
13302            cpr.proc = null;
13303        }
13304        app.pubProviders.clear();
13305
13306        // Take care of any launching providers waiting for this process.
13307        if (checkAppInLaunchingProvidersLocked(app, false)) {
13308            restart = true;
13309        }
13310
13311        // Unregister from connected content providers.
13312        if (!app.conProviders.isEmpty()) {
13313            for (int i=0; i<app.conProviders.size(); i++) {
13314                ContentProviderConnection conn = app.conProviders.get(i);
13315                conn.provider.connections.remove(conn);
13316            }
13317            app.conProviders.clear();
13318        }
13319
13320        // At this point there may be remaining entries in mLaunchingProviders
13321        // where we were the only one waiting, so they are no longer of use.
13322        // Look for these and clean up if found.
13323        // XXX Commented out for now.  Trying to figure out a way to reproduce
13324        // the actual situation to identify what is actually going on.
13325        if (false) {
13326            for (int i=0; i<mLaunchingProviders.size(); i++) {
13327                ContentProviderRecord cpr = (ContentProviderRecord)
13328                        mLaunchingProviders.get(i);
13329                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13330                    synchronized (cpr) {
13331                        cpr.launchingApp = null;
13332                        cpr.notifyAll();
13333                    }
13334                }
13335            }
13336        }
13337
13338        skipCurrentReceiverLocked(app);
13339
13340        // Unregister any receivers.
13341        for (int i=app.receivers.size()-1; i>=0; i--) {
13342            removeReceiverLocked(app.receivers.valueAt(i));
13343        }
13344        app.receivers.clear();
13345
13346        // If the app is undergoing backup, tell the backup manager about it
13347        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13348            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13349                    + mBackupTarget.appInfo + " died during backup");
13350            try {
13351                IBackupManager bm = IBackupManager.Stub.asInterface(
13352                        ServiceManager.getService(Context.BACKUP_SERVICE));
13353                bm.agentDisconnected(app.info.packageName);
13354            } catch (RemoteException e) {
13355                // can't happen; backup manager is local
13356            }
13357        }
13358
13359        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13360            ProcessChangeItem item = mPendingProcessChanges.get(i);
13361            if (item.pid == app.pid) {
13362                mPendingProcessChanges.remove(i);
13363                mAvailProcessChanges.add(item);
13364            }
13365        }
13366        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13367
13368        // If the caller is restarting this app, then leave it in its
13369        // current lists and let the caller take care of it.
13370        if (restarting) {
13371            return;
13372        }
13373
13374        if (!app.persistent || app.isolated) {
13375            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13376                    "Removing non-persistent process during cleanup: " + app);
13377            mProcessNames.remove(app.processName, app.uid);
13378            mIsolatedProcesses.remove(app.uid);
13379            if (mHeavyWeightProcess == app) {
13380                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13381                        mHeavyWeightProcess.userId, 0));
13382                mHeavyWeightProcess = null;
13383            }
13384        } else if (!app.removed) {
13385            // This app is persistent, so we need to keep its record around.
13386            // If it is not already on the pending app list, add it there
13387            // and start a new process for it.
13388            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13389                mPersistentStartingProcesses.add(app);
13390                restart = true;
13391            }
13392        }
13393        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13394                "Clean-up removing on hold: " + app);
13395        mProcessesOnHold.remove(app);
13396
13397        if (app == mHomeProcess) {
13398            mHomeProcess = null;
13399        }
13400        if (app == mPreviousProcess) {
13401            mPreviousProcess = null;
13402        }
13403
13404        if (restart && !app.isolated) {
13405            // We have components that still need to be running in the
13406            // process, so re-launch it.
13407            mProcessNames.put(app.processName, app.uid, app);
13408            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13409        } else if (app.pid > 0 && app.pid != MY_PID) {
13410            // Goodbye!
13411            boolean removed;
13412            synchronized (mPidsSelfLocked) {
13413                mPidsSelfLocked.remove(app.pid);
13414                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13415            }
13416            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13417            if (app.isolated) {
13418                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13419            }
13420            app.setPid(0);
13421        }
13422    }
13423
13424    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13425        // Look through the content providers we are waiting to have launched,
13426        // and if any run in this process then either schedule a restart of
13427        // the process or kill the client waiting for it if this process has
13428        // gone bad.
13429        int NL = mLaunchingProviders.size();
13430        boolean restart = false;
13431        for (int i=0; i<NL; i++) {
13432            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13433            if (cpr.launchingApp == app) {
13434                if (!alwaysBad && !app.bad) {
13435                    restart = true;
13436                } else {
13437                    removeDyingProviderLocked(app, cpr, true);
13438                    // cpr should have been removed from mLaunchingProviders
13439                    NL = mLaunchingProviders.size();
13440                    i--;
13441                }
13442            }
13443        }
13444        return restart;
13445    }
13446
13447    // =========================================================
13448    // SERVICES
13449    // =========================================================
13450
13451    @Override
13452    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13453            int flags) {
13454        enforceNotIsolatedCaller("getServices");
13455        synchronized (this) {
13456            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13457        }
13458    }
13459
13460    @Override
13461    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13462        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13463        synchronized (this) {
13464            return mServices.getRunningServiceControlPanelLocked(name);
13465        }
13466    }
13467
13468    @Override
13469    public ComponentName startService(IApplicationThread caller, Intent service,
13470            String resolvedType, int userId) {
13471        enforceNotIsolatedCaller("startService");
13472        // Refuse possible leaked file descriptors
13473        if (service != null && service.hasFileDescriptors() == true) {
13474            throw new IllegalArgumentException("File descriptors passed in Intent");
13475        }
13476
13477        if (DEBUG_SERVICE)
13478            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13479        synchronized(this) {
13480            final int callingPid = Binder.getCallingPid();
13481            final int callingUid = Binder.getCallingUid();
13482            final long origId = Binder.clearCallingIdentity();
13483            ComponentName res = mServices.startServiceLocked(caller, service,
13484                    resolvedType, callingPid, callingUid, userId);
13485            Binder.restoreCallingIdentity(origId);
13486            return res;
13487        }
13488    }
13489
13490    ComponentName startServiceInPackage(int uid,
13491            Intent service, String resolvedType, int userId) {
13492        synchronized(this) {
13493            if (DEBUG_SERVICE)
13494                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13495            final long origId = Binder.clearCallingIdentity();
13496            ComponentName res = mServices.startServiceLocked(null, service,
13497                    resolvedType, -1, uid, userId);
13498            Binder.restoreCallingIdentity(origId);
13499            return res;
13500        }
13501    }
13502
13503    @Override
13504    public int stopService(IApplicationThread caller, Intent service,
13505            String resolvedType, int userId) {
13506        enforceNotIsolatedCaller("stopService");
13507        // Refuse possible leaked file descriptors
13508        if (service != null && service.hasFileDescriptors() == true) {
13509            throw new IllegalArgumentException("File descriptors passed in Intent");
13510        }
13511
13512        synchronized(this) {
13513            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13514        }
13515    }
13516
13517    @Override
13518    public IBinder peekService(Intent service, String resolvedType) {
13519        enforceNotIsolatedCaller("peekService");
13520        // Refuse possible leaked file descriptors
13521        if (service != null && service.hasFileDescriptors() == true) {
13522            throw new IllegalArgumentException("File descriptors passed in Intent");
13523        }
13524        synchronized(this) {
13525            return mServices.peekServiceLocked(service, resolvedType);
13526        }
13527    }
13528
13529    @Override
13530    public boolean stopServiceToken(ComponentName className, IBinder token,
13531            int startId) {
13532        synchronized(this) {
13533            return mServices.stopServiceTokenLocked(className, token, startId);
13534        }
13535    }
13536
13537    @Override
13538    public void setServiceForeground(ComponentName className, IBinder token,
13539            int id, Notification notification, boolean removeNotification) {
13540        synchronized(this) {
13541            mServices.setServiceForegroundLocked(className, token, id, notification,
13542                    removeNotification);
13543        }
13544    }
13545
13546    @Override
13547    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13548            boolean requireFull, String name, String callerPackage) {
13549        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13550                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13551    }
13552
13553    int unsafeConvertIncomingUser(int userId) {
13554        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13555                ? mCurrentUserId : userId;
13556    }
13557
13558    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13559            int allowMode, String name, String callerPackage) {
13560        final int callingUserId = UserHandle.getUserId(callingUid);
13561        if (callingUserId == userId) {
13562            return userId;
13563        }
13564
13565        // Note that we may be accessing mCurrentUserId outside of a lock...
13566        // shouldn't be a big deal, if this is being called outside
13567        // of a locked context there is intrinsically a race with
13568        // the value the caller will receive and someone else changing it.
13569        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13570        // we will switch to the calling user if access to the current user fails.
13571        int targetUserId = unsafeConvertIncomingUser(userId);
13572
13573        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13574            final boolean allow;
13575            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13576                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13577                // If the caller has this permission, they always pass go.  And collect $200.
13578                allow = true;
13579            } else if (allowMode == ALLOW_FULL_ONLY) {
13580                // We require full access, sucks to be you.
13581                allow = false;
13582            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13583                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13584                // If the caller does not have either permission, they are always doomed.
13585                allow = false;
13586            } else if (allowMode == ALLOW_NON_FULL) {
13587                // We are blanket allowing non-full access, you lucky caller!
13588                allow = true;
13589            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13590                // We may or may not allow this depending on whether the two users are
13591                // in the same profile.
13592                synchronized (mUserProfileGroupIdsSelfLocked) {
13593                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13594                            UserInfo.NO_PROFILE_GROUP_ID);
13595                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13596                            UserInfo.NO_PROFILE_GROUP_ID);
13597                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13598                            && callingProfile == targetProfile;
13599                }
13600            } else {
13601                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13602            }
13603            if (!allow) {
13604                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13605                    // In this case, they would like to just execute as their
13606                    // owner user instead of failing.
13607                    targetUserId = callingUserId;
13608                } else {
13609                    StringBuilder builder = new StringBuilder(128);
13610                    builder.append("Permission Denial: ");
13611                    builder.append(name);
13612                    if (callerPackage != null) {
13613                        builder.append(" from ");
13614                        builder.append(callerPackage);
13615                    }
13616                    builder.append(" asks to run as user ");
13617                    builder.append(userId);
13618                    builder.append(" but is calling from user ");
13619                    builder.append(UserHandle.getUserId(callingUid));
13620                    builder.append("; this requires ");
13621                    builder.append(INTERACT_ACROSS_USERS_FULL);
13622                    if (allowMode != ALLOW_FULL_ONLY) {
13623                        builder.append(" or ");
13624                        builder.append(INTERACT_ACROSS_USERS);
13625                    }
13626                    String msg = builder.toString();
13627                    Slog.w(TAG, msg);
13628                    throw new SecurityException(msg);
13629                }
13630            }
13631        }
13632        if (!allowAll && targetUserId < 0) {
13633            throw new IllegalArgumentException(
13634                    "Call does not support special user #" + targetUserId);
13635        }
13636        return targetUserId;
13637    }
13638
13639    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13640            String className, int flags) {
13641        boolean result = false;
13642        // For apps that don't have pre-defined UIDs, check for permission
13643        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13644            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13645                if (ActivityManager.checkUidPermission(
13646                        INTERACT_ACROSS_USERS,
13647                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13648                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13649                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13650                            + " requests FLAG_SINGLE_USER, but app does not hold "
13651                            + INTERACT_ACROSS_USERS;
13652                    Slog.w(TAG, msg);
13653                    throw new SecurityException(msg);
13654                }
13655                // Permission passed
13656                result = true;
13657            }
13658        } else if ("system".equals(componentProcessName)) {
13659            result = true;
13660        } else {
13661            // App with pre-defined UID, check if it's a persistent app
13662            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13663        }
13664        if (DEBUG_MU) {
13665            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13666                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13667        }
13668        return result;
13669    }
13670
13671    /**
13672     * Checks to see if the caller is in the same app as the singleton
13673     * component, or the component is in a special app. It allows special apps
13674     * to export singleton components but prevents exporting singleton
13675     * components for regular apps.
13676     */
13677    boolean isValidSingletonCall(int callingUid, int componentUid) {
13678        int componentAppId = UserHandle.getAppId(componentUid);
13679        return UserHandle.isSameApp(callingUid, componentUid)
13680                || componentAppId == Process.SYSTEM_UID
13681                || componentAppId == Process.PHONE_UID
13682                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13683                        == PackageManager.PERMISSION_GRANTED;
13684    }
13685
13686    public int bindService(IApplicationThread caller, IBinder token,
13687            Intent service, String resolvedType,
13688            IServiceConnection connection, int flags, int userId) {
13689        enforceNotIsolatedCaller("bindService");
13690        // Refuse possible leaked file descriptors
13691        if (service != null && service.hasFileDescriptors() == true) {
13692            throw new IllegalArgumentException("File descriptors passed in Intent");
13693        }
13694
13695        synchronized(this) {
13696            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13697                    connection, flags, userId);
13698        }
13699    }
13700
13701    public boolean unbindService(IServiceConnection connection) {
13702        synchronized (this) {
13703            return mServices.unbindServiceLocked(connection);
13704        }
13705    }
13706
13707    public void publishService(IBinder token, Intent intent, IBinder service) {
13708        // Refuse possible leaked file descriptors
13709        if (intent != null && intent.hasFileDescriptors() == true) {
13710            throw new IllegalArgumentException("File descriptors passed in Intent");
13711        }
13712
13713        synchronized(this) {
13714            if (!(token instanceof ServiceRecord)) {
13715                throw new IllegalArgumentException("Invalid service token");
13716            }
13717            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13718        }
13719    }
13720
13721    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13722        // Refuse possible leaked file descriptors
13723        if (intent != null && intent.hasFileDescriptors() == true) {
13724            throw new IllegalArgumentException("File descriptors passed in Intent");
13725        }
13726
13727        synchronized(this) {
13728            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13729        }
13730    }
13731
13732    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13733        synchronized(this) {
13734            if (!(token instanceof ServiceRecord)) {
13735                throw new IllegalArgumentException("Invalid service token");
13736            }
13737            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13738        }
13739    }
13740
13741    // =========================================================
13742    // BACKUP AND RESTORE
13743    // =========================================================
13744
13745    // Cause the target app to be launched if necessary and its backup agent
13746    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13747    // activity manager to announce its creation.
13748    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13749        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13750        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13751
13752        synchronized(this) {
13753            // !!! TODO: currently no check here that we're already bound
13754            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13755            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13756            synchronized (stats) {
13757                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13758            }
13759
13760            // Backup agent is now in use, its package can't be stopped.
13761            try {
13762                AppGlobals.getPackageManager().setPackageStoppedState(
13763                        app.packageName, false, UserHandle.getUserId(app.uid));
13764            } catch (RemoteException e) {
13765            } catch (IllegalArgumentException e) {
13766                Slog.w(TAG, "Failed trying to unstop package "
13767                        + app.packageName + ": " + e);
13768            }
13769
13770            BackupRecord r = new BackupRecord(ss, app, backupMode);
13771            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13772                    ? new ComponentName(app.packageName, app.backupAgentName)
13773                    : new ComponentName("android", "FullBackupAgent");
13774            // startProcessLocked() returns existing proc's record if it's already running
13775            ProcessRecord proc = startProcessLocked(app.processName, app,
13776                    false, 0, "backup", hostingName, false, false, false);
13777            if (proc == null) {
13778                Slog.e(TAG, "Unable to start backup agent process " + r);
13779                return false;
13780            }
13781
13782            r.app = proc;
13783            mBackupTarget = r;
13784            mBackupAppName = app.packageName;
13785
13786            // Try not to kill the process during backup
13787            updateOomAdjLocked(proc);
13788
13789            // If the process is already attached, schedule the creation of the backup agent now.
13790            // If it is not yet live, this will be done when it attaches to the framework.
13791            if (proc.thread != null) {
13792                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13793                try {
13794                    proc.thread.scheduleCreateBackupAgent(app,
13795                            compatibilityInfoForPackageLocked(app), backupMode);
13796                } catch (RemoteException e) {
13797                    // Will time out on the backup manager side
13798                }
13799            } else {
13800                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13801            }
13802            // Invariants: at this point, the target app process exists and the application
13803            // is either already running or in the process of coming up.  mBackupTarget and
13804            // mBackupAppName describe the app, so that when it binds back to the AM we
13805            // know that it's scheduled for a backup-agent operation.
13806        }
13807
13808        return true;
13809    }
13810
13811    @Override
13812    public void clearPendingBackup() {
13813        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13814        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13815
13816        synchronized (this) {
13817            mBackupTarget = null;
13818            mBackupAppName = null;
13819        }
13820    }
13821
13822    // A backup agent has just come up
13823    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13824        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13825                + " = " + agent);
13826
13827        synchronized(this) {
13828            if (!agentPackageName.equals(mBackupAppName)) {
13829                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13830                return;
13831            }
13832        }
13833
13834        long oldIdent = Binder.clearCallingIdentity();
13835        try {
13836            IBackupManager bm = IBackupManager.Stub.asInterface(
13837                    ServiceManager.getService(Context.BACKUP_SERVICE));
13838            bm.agentConnected(agentPackageName, agent);
13839        } catch (RemoteException e) {
13840            // can't happen; the backup manager service is local
13841        } catch (Exception e) {
13842            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13843            e.printStackTrace();
13844        } finally {
13845            Binder.restoreCallingIdentity(oldIdent);
13846        }
13847    }
13848
13849    // done with this agent
13850    public void unbindBackupAgent(ApplicationInfo appInfo) {
13851        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13852        if (appInfo == null) {
13853            Slog.w(TAG, "unbind backup agent for null app");
13854            return;
13855        }
13856
13857        synchronized(this) {
13858            try {
13859                if (mBackupAppName == null) {
13860                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13861                    return;
13862                }
13863
13864                if (!mBackupAppName.equals(appInfo.packageName)) {
13865                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13866                    return;
13867                }
13868
13869                // Not backing this app up any more; reset its OOM adjustment
13870                final ProcessRecord proc = mBackupTarget.app;
13871                updateOomAdjLocked(proc);
13872
13873                // If the app crashed during backup, 'thread' will be null here
13874                if (proc.thread != null) {
13875                    try {
13876                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13877                                compatibilityInfoForPackageLocked(appInfo));
13878                    } catch (Exception e) {
13879                        Slog.e(TAG, "Exception when unbinding backup agent:");
13880                        e.printStackTrace();
13881                    }
13882                }
13883            } finally {
13884                mBackupTarget = null;
13885                mBackupAppName = null;
13886            }
13887        }
13888    }
13889    // =========================================================
13890    // BROADCASTS
13891    // =========================================================
13892
13893    private final List getStickiesLocked(String action, IntentFilter filter,
13894            List cur, int userId) {
13895        final ContentResolver resolver = mContext.getContentResolver();
13896        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13897        if (stickies == null) {
13898            return cur;
13899        }
13900        final ArrayList<Intent> list = stickies.get(action);
13901        if (list == null) {
13902            return cur;
13903        }
13904        int N = list.size();
13905        for (int i=0; i<N; i++) {
13906            Intent intent = list.get(i);
13907            if (filter.match(resolver, intent, true, TAG) >= 0) {
13908                if (cur == null) {
13909                    cur = new ArrayList<Intent>();
13910                }
13911                cur.add(intent);
13912            }
13913        }
13914        return cur;
13915    }
13916
13917    boolean isPendingBroadcastProcessLocked(int pid) {
13918        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13919                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13920    }
13921
13922    void skipPendingBroadcastLocked(int pid) {
13923            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13924            for (BroadcastQueue queue : mBroadcastQueues) {
13925                queue.skipPendingBroadcastLocked(pid);
13926            }
13927    }
13928
13929    // The app just attached; send any pending broadcasts that it should receive
13930    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13931        boolean didSomething = false;
13932        for (BroadcastQueue queue : mBroadcastQueues) {
13933            didSomething |= queue.sendPendingBroadcastsLocked(app);
13934        }
13935        return didSomething;
13936    }
13937
13938    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13939            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13940        enforceNotIsolatedCaller("registerReceiver");
13941        int callingUid;
13942        int callingPid;
13943        synchronized(this) {
13944            ProcessRecord callerApp = null;
13945            if (caller != null) {
13946                callerApp = getRecordForAppLocked(caller);
13947                if (callerApp == null) {
13948                    throw new SecurityException(
13949                            "Unable to find app for caller " + caller
13950                            + " (pid=" + Binder.getCallingPid()
13951                            + ") when registering receiver " + receiver);
13952                }
13953                if (callerApp.info.uid != Process.SYSTEM_UID &&
13954                        !callerApp.pkgList.containsKey(callerPackage) &&
13955                        !"android".equals(callerPackage)) {
13956                    throw new SecurityException("Given caller package " + callerPackage
13957                            + " is not running in process " + callerApp);
13958                }
13959                callingUid = callerApp.info.uid;
13960                callingPid = callerApp.pid;
13961            } else {
13962                callerPackage = null;
13963                callingUid = Binder.getCallingUid();
13964                callingPid = Binder.getCallingPid();
13965            }
13966
13967            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13968                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
13969
13970            List allSticky = null;
13971
13972            // Look for any matching sticky broadcasts...
13973            Iterator actions = filter.actionsIterator();
13974            if (actions != null) {
13975                while (actions.hasNext()) {
13976                    String action = (String)actions.next();
13977                    allSticky = getStickiesLocked(action, filter, allSticky,
13978                            UserHandle.USER_ALL);
13979                    allSticky = getStickiesLocked(action, filter, allSticky,
13980                            UserHandle.getUserId(callingUid));
13981                }
13982            } else {
13983                allSticky = getStickiesLocked(null, filter, allSticky,
13984                        UserHandle.USER_ALL);
13985                allSticky = getStickiesLocked(null, filter, allSticky,
13986                        UserHandle.getUserId(callingUid));
13987            }
13988
13989            // The first sticky in the list is returned directly back to
13990            // the client.
13991            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13992
13993            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13994                    + ": " + sticky);
13995
13996            if (receiver == null) {
13997                return sticky;
13998            }
13999
14000            ReceiverList rl
14001                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14002            if (rl == null) {
14003                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14004                        userId, receiver);
14005                if (rl.app != null) {
14006                    rl.app.receivers.add(rl);
14007                } else {
14008                    try {
14009                        receiver.asBinder().linkToDeath(rl, 0);
14010                    } catch (RemoteException e) {
14011                        return sticky;
14012                    }
14013                    rl.linkedToDeath = true;
14014                }
14015                mRegisteredReceivers.put(receiver.asBinder(), rl);
14016            } else if (rl.uid != callingUid) {
14017                throw new IllegalArgumentException(
14018                        "Receiver requested to register for uid " + callingUid
14019                        + " was previously registered for uid " + rl.uid);
14020            } else if (rl.pid != callingPid) {
14021                throw new IllegalArgumentException(
14022                        "Receiver requested to register for pid " + callingPid
14023                        + " was previously registered for pid " + rl.pid);
14024            } else if (rl.userId != userId) {
14025                throw new IllegalArgumentException(
14026                        "Receiver requested to register for user " + userId
14027                        + " was previously registered for user " + rl.userId);
14028            }
14029            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14030                    permission, callingUid, userId);
14031            rl.add(bf);
14032            if (!bf.debugCheck()) {
14033                Slog.w(TAG, "==> For Dynamic broadast");
14034            }
14035            mReceiverResolver.addFilter(bf);
14036
14037            // Enqueue broadcasts for all existing stickies that match
14038            // this filter.
14039            if (allSticky != null) {
14040                ArrayList receivers = new ArrayList();
14041                receivers.add(bf);
14042
14043                int N = allSticky.size();
14044                for (int i=0; i<N; i++) {
14045                    Intent intent = (Intent)allSticky.get(i);
14046                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14047                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14048                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14049                            null, null, false, true, true, -1);
14050                    queue.enqueueParallelBroadcastLocked(r);
14051                    queue.scheduleBroadcastsLocked();
14052                }
14053            }
14054
14055            return sticky;
14056        }
14057    }
14058
14059    public void unregisterReceiver(IIntentReceiver receiver) {
14060        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14061
14062        final long origId = Binder.clearCallingIdentity();
14063        try {
14064            boolean doTrim = false;
14065
14066            synchronized(this) {
14067                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14068                if (rl != null) {
14069                    if (rl.curBroadcast != null) {
14070                        BroadcastRecord r = rl.curBroadcast;
14071                        final boolean doNext = finishReceiverLocked(
14072                                receiver.asBinder(), r.resultCode, r.resultData,
14073                                r.resultExtras, r.resultAbort);
14074                        if (doNext) {
14075                            doTrim = true;
14076                            r.queue.processNextBroadcast(false);
14077                        }
14078                    }
14079
14080                    if (rl.app != null) {
14081                        rl.app.receivers.remove(rl);
14082                    }
14083                    removeReceiverLocked(rl);
14084                    if (rl.linkedToDeath) {
14085                        rl.linkedToDeath = false;
14086                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14087                    }
14088                }
14089            }
14090
14091            // If we actually concluded any broadcasts, we might now be able
14092            // to trim the recipients' apps from our working set
14093            if (doTrim) {
14094                trimApplications();
14095                return;
14096            }
14097
14098        } finally {
14099            Binder.restoreCallingIdentity(origId);
14100        }
14101    }
14102
14103    void removeReceiverLocked(ReceiverList rl) {
14104        mRegisteredReceivers.remove(rl.receiver.asBinder());
14105        int N = rl.size();
14106        for (int i=0; i<N; i++) {
14107            mReceiverResolver.removeFilter(rl.get(i));
14108        }
14109    }
14110
14111    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14112        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14113            ProcessRecord r = mLruProcesses.get(i);
14114            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14115                try {
14116                    r.thread.dispatchPackageBroadcast(cmd, packages);
14117                } catch (RemoteException ex) {
14118                }
14119            }
14120        }
14121    }
14122
14123    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14124            int[] users) {
14125        List<ResolveInfo> receivers = null;
14126        try {
14127            HashSet<ComponentName> singleUserReceivers = null;
14128            boolean scannedFirstReceivers = false;
14129            for (int user : users) {
14130                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14131                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14132                if (user != 0 && newReceivers != null) {
14133                    // If this is not the primary user, we need to check for
14134                    // any receivers that should be filtered out.
14135                    for (int i=0; i<newReceivers.size(); i++) {
14136                        ResolveInfo ri = newReceivers.get(i);
14137                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14138                            newReceivers.remove(i);
14139                            i--;
14140                        }
14141                    }
14142                }
14143                if (newReceivers != null && newReceivers.size() == 0) {
14144                    newReceivers = null;
14145                }
14146                if (receivers == null) {
14147                    receivers = newReceivers;
14148                } else if (newReceivers != null) {
14149                    // We need to concatenate the additional receivers
14150                    // found with what we have do far.  This would be easy,
14151                    // but we also need to de-dup any receivers that are
14152                    // singleUser.
14153                    if (!scannedFirstReceivers) {
14154                        // Collect any single user receivers we had already retrieved.
14155                        scannedFirstReceivers = true;
14156                        for (int i=0; i<receivers.size(); i++) {
14157                            ResolveInfo ri = receivers.get(i);
14158                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14159                                ComponentName cn = new ComponentName(
14160                                        ri.activityInfo.packageName, ri.activityInfo.name);
14161                                if (singleUserReceivers == null) {
14162                                    singleUserReceivers = new HashSet<ComponentName>();
14163                                }
14164                                singleUserReceivers.add(cn);
14165                            }
14166                        }
14167                    }
14168                    // Add the new results to the existing results, tracking
14169                    // and de-dupping single user receivers.
14170                    for (int i=0; i<newReceivers.size(); i++) {
14171                        ResolveInfo ri = newReceivers.get(i);
14172                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14173                            ComponentName cn = new ComponentName(
14174                                    ri.activityInfo.packageName, ri.activityInfo.name);
14175                            if (singleUserReceivers == null) {
14176                                singleUserReceivers = new HashSet<ComponentName>();
14177                            }
14178                            if (!singleUserReceivers.contains(cn)) {
14179                                singleUserReceivers.add(cn);
14180                                receivers.add(ri);
14181                            }
14182                        } else {
14183                            receivers.add(ri);
14184                        }
14185                    }
14186                }
14187            }
14188        } catch (RemoteException ex) {
14189            // pm is in same process, this will never happen.
14190        }
14191        return receivers;
14192    }
14193
14194    private final int broadcastIntentLocked(ProcessRecord callerApp,
14195            String callerPackage, Intent intent, String resolvedType,
14196            IIntentReceiver resultTo, int resultCode, String resultData,
14197            Bundle map, String requiredPermission, int appOp,
14198            boolean ordered, boolean sticky, int callingPid, int callingUid,
14199            int userId) {
14200        intent = new Intent(intent);
14201
14202        // By default broadcasts do not go to stopped apps.
14203        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14204
14205        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14206            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14207            + " ordered=" + ordered + " userid=" + userId);
14208        if ((resultTo != null) && !ordered) {
14209            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14210        }
14211
14212        userId = handleIncomingUser(callingPid, callingUid, userId,
14213                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14214
14215        // Make sure that the user who is receiving this broadcast is started.
14216        // If not, we will just skip it.
14217
14218
14219        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14220            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14221                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14222                Slog.w(TAG, "Skipping broadcast of " + intent
14223                        + ": user " + userId + " is stopped");
14224                return ActivityManager.BROADCAST_SUCCESS;
14225            }
14226        }
14227
14228        /*
14229         * Prevent non-system code (defined here to be non-persistent
14230         * processes) from sending protected broadcasts.
14231         */
14232        int callingAppId = UserHandle.getAppId(callingUid);
14233        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14234            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14235            || callingAppId == Process.NFC_UID || callingUid == 0) {
14236            // Always okay.
14237        } else if (callerApp == null || !callerApp.persistent) {
14238            try {
14239                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14240                        intent.getAction())) {
14241                    String msg = "Permission Denial: not allowed to send broadcast "
14242                            + intent.getAction() + " from pid="
14243                            + callingPid + ", uid=" + callingUid;
14244                    Slog.w(TAG, msg);
14245                    throw new SecurityException(msg);
14246                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14247                    // Special case for compatibility: we don't want apps to send this,
14248                    // but historically it has not been protected and apps may be using it
14249                    // to poke their own app widget.  So, instead of making it protected,
14250                    // just limit it to the caller.
14251                    if (callerApp == null) {
14252                        String msg = "Permission Denial: not allowed to send broadcast "
14253                                + intent.getAction() + " from unknown caller.";
14254                        Slog.w(TAG, msg);
14255                        throw new SecurityException(msg);
14256                    } else if (intent.getComponent() != null) {
14257                        // They are good enough to send to an explicit component...  verify
14258                        // it is being sent to the calling app.
14259                        if (!intent.getComponent().getPackageName().equals(
14260                                callerApp.info.packageName)) {
14261                            String msg = "Permission Denial: not allowed to send broadcast "
14262                                    + intent.getAction() + " to "
14263                                    + intent.getComponent().getPackageName() + " from "
14264                                    + callerApp.info.packageName;
14265                            Slog.w(TAG, msg);
14266                            throw new SecurityException(msg);
14267                        }
14268                    } else {
14269                        // Limit broadcast to their own package.
14270                        intent.setPackage(callerApp.info.packageName);
14271                    }
14272                }
14273            } catch (RemoteException e) {
14274                Slog.w(TAG, "Remote exception", e);
14275                return ActivityManager.BROADCAST_SUCCESS;
14276            }
14277        }
14278
14279        // Handle special intents: if this broadcast is from the package
14280        // manager about a package being removed, we need to remove all of
14281        // its activities from the history stack.
14282        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14283                intent.getAction());
14284        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14285                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14286                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14287                || uidRemoved) {
14288            if (checkComponentPermission(
14289                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14290                    callingPid, callingUid, -1, true)
14291                    == PackageManager.PERMISSION_GRANTED) {
14292                if (uidRemoved) {
14293                    final Bundle intentExtras = intent.getExtras();
14294                    final int uid = intentExtras != null
14295                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14296                    if (uid >= 0) {
14297                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14298                        synchronized (bs) {
14299                            bs.removeUidStatsLocked(uid);
14300                        }
14301                        mAppOpsService.uidRemoved(uid);
14302                    }
14303                } else {
14304                    // If resources are unavailable just force stop all
14305                    // those packages and flush the attribute cache as well.
14306                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14307                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14308                        if (list != null && (list.length > 0)) {
14309                            for (String pkg : list) {
14310                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14311                                        "storage unmount");
14312                            }
14313                            sendPackageBroadcastLocked(
14314                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14315                        }
14316                    } else {
14317                        Uri data = intent.getData();
14318                        String ssp;
14319                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14320                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14321                                    intent.getAction());
14322                            boolean fullUninstall = removed &&
14323                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14324                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14325                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14326                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14327                                        false, fullUninstall, userId,
14328                                        removed ? "pkg removed" : "pkg changed");
14329                            }
14330                            if (removed) {
14331                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14332                                        new String[] {ssp}, userId);
14333                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14334                                    mAppOpsService.packageRemoved(
14335                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14336
14337                                    // Remove all permissions granted from/to this package
14338                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14339                                }
14340                            }
14341                        }
14342                    }
14343                }
14344            } else {
14345                String msg = "Permission Denial: " + intent.getAction()
14346                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14347                        + ", uid=" + callingUid + ")"
14348                        + " requires "
14349                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14350                Slog.w(TAG, msg);
14351                throw new SecurityException(msg);
14352            }
14353
14354        // Special case for adding a package: by default turn on compatibility
14355        // mode.
14356        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14357            Uri data = intent.getData();
14358            String ssp;
14359            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14360                mCompatModePackages.handlePackageAddedLocked(ssp,
14361                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14362            }
14363        }
14364
14365        /*
14366         * If this is the time zone changed action, queue up a message that will reset the timezone
14367         * of all currently running processes. This message will get queued up before the broadcast
14368         * happens.
14369         */
14370        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14371            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14372        }
14373
14374        /*
14375         * If the user set the time, let all running processes know.
14376         */
14377        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14378            final int is24Hour = intent.getBooleanExtra(
14379                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14380            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14381        }
14382
14383        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14384            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14385        }
14386
14387        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14388            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14389            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14390        }
14391
14392        // Add to the sticky list if requested.
14393        if (sticky) {
14394            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14395                    callingPid, callingUid)
14396                    != PackageManager.PERMISSION_GRANTED) {
14397                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14398                        + callingPid + ", uid=" + callingUid
14399                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14400                Slog.w(TAG, msg);
14401                throw new SecurityException(msg);
14402            }
14403            if (requiredPermission != null) {
14404                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14405                        + " and enforce permission " + requiredPermission);
14406                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14407            }
14408            if (intent.getComponent() != null) {
14409                throw new SecurityException(
14410                        "Sticky broadcasts can't target a specific component");
14411            }
14412            // We use userId directly here, since the "all" target is maintained
14413            // as a separate set of sticky broadcasts.
14414            if (userId != UserHandle.USER_ALL) {
14415                // But first, if this is not a broadcast to all users, then
14416                // make sure it doesn't conflict with an existing broadcast to
14417                // all users.
14418                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14419                        UserHandle.USER_ALL);
14420                if (stickies != null) {
14421                    ArrayList<Intent> list = stickies.get(intent.getAction());
14422                    if (list != null) {
14423                        int N = list.size();
14424                        int i;
14425                        for (i=0; i<N; i++) {
14426                            if (intent.filterEquals(list.get(i))) {
14427                                throw new IllegalArgumentException(
14428                                        "Sticky broadcast " + intent + " for user "
14429                                        + userId + " conflicts with existing global broadcast");
14430                            }
14431                        }
14432                    }
14433                }
14434            }
14435            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14436            if (stickies == null) {
14437                stickies = new ArrayMap<String, ArrayList<Intent>>();
14438                mStickyBroadcasts.put(userId, stickies);
14439            }
14440            ArrayList<Intent> list = stickies.get(intent.getAction());
14441            if (list == null) {
14442                list = new ArrayList<Intent>();
14443                stickies.put(intent.getAction(), list);
14444            }
14445            int N = list.size();
14446            int i;
14447            for (i=0; i<N; i++) {
14448                if (intent.filterEquals(list.get(i))) {
14449                    // This sticky already exists, replace it.
14450                    list.set(i, new Intent(intent));
14451                    break;
14452                }
14453            }
14454            if (i >= N) {
14455                list.add(new Intent(intent));
14456            }
14457        }
14458
14459        int[] users;
14460        if (userId == UserHandle.USER_ALL) {
14461            // Caller wants broadcast to go to all started users.
14462            users = mStartedUserArray;
14463        } else {
14464            // Caller wants broadcast to go to one specific user.
14465            users = new int[] {userId};
14466        }
14467
14468        // Figure out who all will receive this broadcast.
14469        List receivers = null;
14470        List<BroadcastFilter> registeredReceivers = null;
14471        // Need to resolve the intent to interested receivers...
14472        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14473                 == 0) {
14474            receivers = collectReceiverComponents(intent, resolvedType, users);
14475        }
14476        if (intent.getComponent() == null) {
14477            registeredReceivers = mReceiverResolver.queryIntent(intent,
14478                    resolvedType, false, userId);
14479        }
14480
14481        final boolean replacePending =
14482                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14483
14484        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14485                + " replacePending=" + replacePending);
14486
14487        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14488        if (!ordered && NR > 0) {
14489            // If we are not serializing this broadcast, then send the
14490            // registered receivers separately so they don't wait for the
14491            // components to be launched.
14492            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14493            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14494                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14495                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14496                    ordered, sticky, false, userId);
14497            if (DEBUG_BROADCAST) Slog.v(
14498                    TAG, "Enqueueing parallel broadcast " + r);
14499            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14500            if (!replaced) {
14501                queue.enqueueParallelBroadcastLocked(r);
14502                queue.scheduleBroadcastsLocked();
14503            }
14504            registeredReceivers = null;
14505            NR = 0;
14506        }
14507
14508        // Merge into one list.
14509        int ir = 0;
14510        if (receivers != null) {
14511            // A special case for PACKAGE_ADDED: do not allow the package
14512            // being added to see this broadcast.  This prevents them from
14513            // using this as a back door to get run as soon as they are
14514            // installed.  Maybe in the future we want to have a special install
14515            // broadcast or such for apps, but we'd like to deliberately make
14516            // this decision.
14517            String skipPackages[] = null;
14518            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14519                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14520                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14521                Uri data = intent.getData();
14522                if (data != null) {
14523                    String pkgName = data.getSchemeSpecificPart();
14524                    if (pkgName != null) {
14525                        skipPackages = new String[] { pkgName };
14526                    }
14527                }
14528            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14529                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14530            }
14531            if (skipPackages != null && (skipPackages.length > 0)) {
14532                for (String skipPackage : skipPackages) {
14533                    if (skipPackage != null) {
14534                        int NT = receivers.size();
14535                        for (int it=0; it<NT; it++) {
14536                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14537                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14538                                receivers.remove(it);
14539                                it--;
14540                                NT--;
14541                            }
14542                        }
14543                    }
14544                }
14545            }
14546
14547            int NT = receivers != null ? receivers.size() : 0;
14548            int it = 0;
14549            ResolveInfo curt = null;
14550            BroadcastFilter curr = null;
14551            while (it < NT && ir < NR) {
14552                if (curt == null) {
14553                    curt = (ResolveInfo)receivers.get(it);
14554                }
14555                if (curr == null) {
14556                    curr = registeredReceivers.get(ir);
14557                }
14558                if (curr.getPriority() >= curt.priority) {
14559                    // Insert this broadcast record into the final list.
14560                    receivers.add(it, curr);
14561                    ir++;
14562                    curr = null;
14563                    it++;
14564                    NT++;
14565                } else {
14566                    // Skip to the next ResolveInfo in the final list.
14567                    it++;
14568                    curt = null;
14569                }
14570            }
14571        }
14572        while (ir < NR) {
14573            if (receivers == null) {
14574                receivers = new ArrayList();
14575            }
14576            receivers.add(registeredReceivers.get(ir));
14577            ir++;
14578        }
14579
14580        if ((receivers != null && receivers.size() > 0)
14581                || resultTo != null) {
14582            BroadcastQueue queue = broadcastQueueForIntent(intent);
14583            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14584                    callerPackage, callingPid, callingUid, resolvedType,
14585                    requiredPermission, appOp, receivers, resultTo, resultCode,
14586                    resultData, map, ordered, sticky, false, userId);
14587            if (DEBUG_BROADCAST) Slog.v(
14588                    TAG, "Enqueueing ordered broadcast " + r
14589                    + ": prev had " + queue.mOrderedBroadcasts.size());
14590            if (DEBUG_BROADCAST) {
14591                int seq = r.intent.getIntExtra("seq", -1);
14592                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14593            }
14594            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14595            if (!replaced) {
14596                queue.enqueueOrderedBroadcastLocked(r);
14597                queue.scheduleBroadcastsLocked();
14598            }
14599        }
14600
14601        return ActivityManager.BROADCAST_SUCCESS;
14602    }
14603
14604    final Intent verifyBroadcastLocked(Intent intent) {
14605        // Refuse possible leaked file descriptors
14606        if (intent != null && intent.hasFileDescriptors() == true) {
14607            throw new IllegalArgumentException("File descriptors passed in Intent");
14608        }
14609
14610        int flags = intent.getFlags();
14611
14612        if (!mProcessesReady) {
14613            // if the caller really truly claims to know what they're doing, go
14614            // ahead and allow the broadcast without launching any receivers
14615            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14616                intent = new Intent(intent);
14617                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14618            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14619                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14620                        + " before boot completion");
14621                throw new IllegalStateException("Cannot broadcast before boot completed");
14622            }
14623        }
14624
14625        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14626            throw new IllegalArgumentException(
14627                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14628        }
14629
14630        return intent;
14631    }
14632
14633    public final int broadcastIntent(IApplicationThread caller,
14634            Intent intent, String resolvedType, IIntentReceiver resultTo,
14635            int resultCode, String resultData, Bundle map,
14636            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14637        enforceNotIsolatedCaller("broadcastIntent");
14638        synchronized(this) {
14639            intent = verifyBroadcastLocked(intent);
14640
14641            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14642            final int callingPid = Binder.getCallingPid();
14643            final int callingUid = Binder.getCallingUid();
14644            final long origId = Binder.clearCallingIdentity();
14645            int res = broadcastIntentLocked(callerApp,
14646                    callerApp != null ? callerApp.info.packageName : null,
14647                    intent, resolvedType, resultTo,
14648                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14649                    callingPid, callingUid, userId);
14650            Binder.restoreCallingIdentity(origId);
14651            return res;
14652        }
14653    }
14654
14655    int broadcastIntentInPackage(String packageName, int uid,
14656            Intent intent, String resolvedType, IIntentReceiver resultTo,
14657            int resultCode, String resultData, Bundle map,
14658            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14659        synchronized(this) {
14660            intent = verifyBroadcastLocked(intent);
14661
14662            final long origId = Binder.clearCallingIdentity();
14663            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14664                    resultTo, resultCode, resultData, map, requiredPermission,
14665                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14666            Binder.restoreCallingIdentity(origId);
14667            return res;
14668        }
14669    }
14670
14671    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14672        // Refuse possible leaked file descriptors
14673        if (intent != null && intent.hasFileDescriptors() == true) {
14674            throw new IllegalArgumentException("File descriptors passed in Intent");
14675        }
14676
14677        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14678                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14679
14680        synchronized(this) {
14681            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14682                    != PackageManager.PERMISSION_GRANTED) {
14683                String msg = "Permission Denial: unbroadcastIntent() from pid="
14684                        + Binder.getCallingPid()
14685                        + ", uid=" + Binder.getCallingUid()
14686                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14687                Slog.w(TAG, msg);
14688                throw new SecurityException(msg);
14689            }
14690            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14691            if (stickies != null) {
14692                ArrayList<Intent> list = stickies.get(intent.getAction());
14693                if (list != null) {
14694                    int N = list.size();
14695                    int i;
14696                    for (i=0; i<N; i++) {
14697                        if (intent.filterEquals(list.get(i))) {
14698                            list.remove(i);
14699                            break;
14700                        }
14701                    }
14702                    if (list.size() <= 0) {
14703                        stickies.remove(intent.getAction());
14704                    }
14705                }
14706                if (stickies.size() <= 0) {
14707                    mStickyBroadcasts.remove(userId);
14708                }
14709            }
14710        }
14711    }
14712
14713    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14714            String resultData, Bundle resultExtras, boolean resultAbort) {
14715        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14716        if (r == null) {
14717            Slog.w(TAG, "finishReceiver called but not found on queue");
14718            return false;
14719        }
14720
14721        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14722    }
14723
14724    void backgroundServicesFinishedLocked(int userId) {
14725        for (BroadcastQueue queue : mBroadcastQueues) {
14726            queue.backgroundServicesFinishedLocked(userId);
14727        }
14728    }
14729
14730    public void finishReceiver(IBinder who, int resultCode, String resultData,
14731            Bundle resultExtras, boolean resultAbort) {
14732        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14733
14734        // Refuse possible leaked file descriptors
14735        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14736            throw new IllegalArgumentException("File descriptors passed in Bundle");
14737        }
14738
14739        final long origId = Binder.clearCallingIdentity();
14740        try {
14741            boolean doNext = false;
14742            BroadcastRecord r;
14743
14744            synchronized(this) {
14745                r = broadcastRecordForReceiverLocked(who);
14746                if (r != null) {
14747                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14748                        resultData, resultExtras, resultAbort, true);
14749                }
14750            }
14751
14752            if (doNext) {
14753                r.queue.processNextBroadcast(false);
14754            }
14755            trimApplications();
14756        } finally {
14757            Binder.restoreCallingIdentity(origId);
14758        }
14759    }
14760
14761    // =========================================================
14762    // INSTRUMENTATION
14763    // =========================================================
14764
14765    public boolean startInstrumentation(ComponentName className,
14766            String profileFile, int flags, Bundle arguments,
14767            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14768            int userId, String abiOverride) {
14769        enforceNotIsolatedCaller("startInstrumentation");
14770        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14771                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14772        // Refuse possible leaked file descriptors
14773        if (arguments != null && arguments.hasFileDescriptors()) {
14774            throw new IllegalArgumentException("File descriptors passed in Bundle");
14775        }
14776
14777        synchronized(this) {
14778            InstrumentationInfo ii = null;
14779            ApplicationInfo ai = null;
14780            try {
14781                ii = mContext.getPackageManager().getInstrumentationInfo(
14782                    className, STOCK_PM_FLAGS);
14783                ai = AppGlobals.getPackageManager().getApplicationInfo(
14784                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14785            } catch (PackageManager.NameNotFoundException e) {
14786            } catch (RemoteException e) {
14787            }
14788            if (ii == null) {
14789                reportStartInstrumentationFailure(watcher, className,
14790                        "Unable to find instrumentation info for: " + className);
14791                return false;
14792            }
14793            if (ai == null) {
14794                reportStartInstrumentationFailure(watcher, className,
14795                        "Unable to find instrumentation target package: " + ii.targetPackage);
14796                return false;
14797            }
14798
14799            int match = mContext.getPackageManager().checkSignatures(
14800                    ii.targetPackage, ii.packageName);
14801            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14802                String msg = "Permission Denial: starting instrumentation "
14803                        + className + " from pid="
14804                        + Binder.getCallingPid()
14805                        + ", uid=" + Binder.getCallingPid()
14806                        + " not allowed because package " + ii.packageName
14807                        + " does not have a signature matching the target "
14808                        + ii.targetPackage;
14809                reportStartInstrumentationFailure(watcher, className, msg);
14810                throw new SecurityException(msg);
14811            }
14812
14813            final long origId = Binder.clearCallingIdentity();
14814            // Instrumentation can kill and relaunch even persistent processes
14815            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14816                    "start instr");
14817            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14818            app.instrumentationClass = className;
14819            app.instrumentationInfo = ai;
14820            app.instrumentationProfileFile = profileFile;
14821            app.instrumentationArguments = arguments;
14822            app.instrumentationWatcher = watcher;
14823            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14824            app.instrumentationResultClass = className;
14825            Binder.restoreCallingIdentity(origId);
14826        }
14827
14828        return true;
14829    }
14830
14831    /**
14832     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14833     * error to the logs, but if somebody is watching, send the report there too.  This enables
14834     * the "am" command to report errors with more information.
14835     *
14836     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14837     * @param cn The component name of the instrumentation.
14838     * @param report The error report.
14839     */
14840    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14841            ComponentName cn, String report) {
14842        Slog.w(TAG, report);
14843        try {
14844            if (watcher != null) {
14845                Bundle results = new Bundle();
14846                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14847                results.putString("Error", report);
14848                watcher.instrumentationStatus(cn, -1, results);
14849            }
14850        } catch (RemoteException e) {
14851            Slog.w(TAG, e);
14852        }
14853    }
14854
14855    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14856        if (app.instrumentationWatcher != null) {
14857            try {
14858                // NOTE:  IInstrumentationWatcher *must* be oneway here
14859                app.instrumentationWatcher.instrumentationFinished(
14860                    app.instrumentationClass,
14861                    resultCode,
14862                    results);
14863            } catch (RemoteException e) {
14864            }
14865        }
14866        if (app.instrumentationUiAutomationConnection != null) {
14867            try {
14868                app.instrumentationUiAutomationConnection.shutdown();
14869            } catch (RemoteException re) {
14870                /* ignore */
14871            }
14872            // Only a UiAutomation can set this flag and now that
14873            // it is finished we make sure it is reset to its default.
14874            mUserIsMonkey = false;
14875        }
14876        app.instrumentationWatcher = null;
14877        app.instrumentationUiAutomationConnection = null;
14878        app.instrumentationClass = null;
14879        app.instrumentationInfo = null;
14880        app.instrumentationProfileFile = null;
14881        app.instrumentationArguments = null;
14882
14883        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14884                "finished inst");
14885    }
14886
14887    public void finishInstrumentation(IApplicationThread target,
14888            int resultCode, Bundle results) {
14889        int userId = UserHandle.getCallingUserId();
14890        // Refuse possible leaked file descriptors
14891        if (results != null && results.hasFileDescriptors()) {
14892            throw new IllegalArgumentException("File descriptors passed in Intent");
14893        }
14894
14895        synchronized(this) {
14896            ProcessRecord app = getRecordForAppLocked(target);
14897            if (app == null) {
14898                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14899                return;
14900            }
14901            final long origId = Binder.clearCallingIdentity();
14902            finishInstrumentationLocked(app, resultCode, results);
14903            Binder.restoreCallingIdentity(origId);
14904        }
14905    }
14906
14907    // =========================================================
14908    // CONFIGURATION
14909    // =========================================================
14910
14911    public ConfigurationInfo getDeviceConfigurationInfo() {
14912        ConfigurationInfo config = new ConfigurationInfo();
14913        synchronized (this) {
14914            config.reqTouchScreen = mConfiguration.touchscreen;
14915            config.reqKeyboardType = mConfiguration.keyboard;
14916            config.reqNavigation = mConfiguration.navigation;
14917            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14918                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14919                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14920            }
14921            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14922                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14923                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14924            }
14925            config.reqGlEsVersion = GL_ES_VERSION;
14926        }
14927        return config;
14928    }
14929
14930    ActivityStack getFocusedStack() {
14931        return mStackSupervisor.getFocusedStack();
14932    }
14933
14934    public Configuration getConfiguration() {
14935        Configuration ci;
14936        synchronized(this) {
14937            ci = new Configuration(mConfiguration);
14938        }
14939        return ci;
14940    }
14941
14942    public void updatePersistentConfiguration(Configuration values) {
14943        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14944                "updateConfiguration()");
14945        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14946                "updateConfiguration()");
14947        if (values == null) {
14948            throw new NullPointerException("Configuration must not be null");
14949        }
14950
14951        synchronized(this) {
14952            final long origId = Binder.clearCallingIdentity();
14953            updateConfigurationLocked(values, null, true, false);
14954            Binder.restoreCallingIdentity(origId);
14955        }
14956    }
14957
14958    public void updateConfiguration(Configuration values) {
14959        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14960                "updateConfiguration()");
14961
14962        synchronized(this) {
14963            if (values == null && mWindowManager != null) {
14964                // sentinel: fetch the current configuration from the window manager
14965                values = mWindowManager.computeNewConfiguration();
14966            }
14967
14968            if (mWindowManager != null) {
14969                mProcessList.applyDisplaySize(mWindowManager);
14970            }
14971
14972            final long origId = Binder.clearCallingIdentity();
14973            if (values != null) {
14974                Settings.System.clearConfiguration(values);
14975            }
14976            updateConfigurationLocked(values, null, false, false);
14977            Binder.restoreCallingIdentity(origId);
14978        }
14979    }
14980
14981    /**
14982     * Do either or both things: (1) change the current configuration, and (2)
14983     * make sure the given activity is running with the (now) current
14984     * configuration.  Returns true if the activity has been left running, or
14985     * false if <var>starting</var> is being destroyed to match the new
14986     * configuration.
14987     * @param persistent TODO
14988     */
14989    boolean updateConfigurationLocked(Configuration values,
14990            ActivityRecord starting, boolean persistent, boolean initLocale) {
14991        int changes = 0;
14992
14993        if (values != null) {
14994            Configuration newConfig = new Configuration(mConfiguration);
14995            changes = newConfig.updateFrom(values);
14996            if (changes != 0) {
14997                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14998                    Slog.i(TAG, "Updating configuration to: " + values);
14999                }
15000
15001                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15002
15003                if (values.locale != null && !initLocale) {
15004                    saveLocaleLocked(values.locale,
15005                                     !values.locale.equals(mConfiguration.locale),
15006                                     values.userSetLocale);
15007                }
15008
15009                mConfigurationSeq++;
15010                if (mConfigurationSeq <= 0) {
15011                    mConfigurationSeq = 1;
15012                }
15013                newConfig.seq = mConfigurationSeq;
15014                mConfiguration = newConfig;
15015                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15016                //mUsageStatsService.noteStartConfig(newConfig);
15017
15018                final Configuration configCopy = new Configuration(mConfiguration);
15019
15020                // TODO: If our config changes, should we auto dismiss any currently
15021                // showing dialogs?
15022                mShowDialogs = shouldShowDialogs(newConfig);
15023
15024                AttributeCache ac = AttributeCache.instance();
15025                if (ac != null) {
15026                    ac.updateConfiguration(configCopy);
15027                }
15028
15029                // Make sure all resources in our process are updated
15030                // right now, so that anyone who is going to retrieve
15031                // resource values after we return will be sure to get
15032                // the new ones.  This is especially important during
15033                // boot, where the first config change needs to guarantee
15034                // all resources have that config before following boot
15035                // code is executed.
15036                mSystemThread.applyConfigurationToResources(configCopy);
15037
15038                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15039                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15040                    msg.obj = new Configuration(configCopy);
15041                    mHandler.sendMessage(msg);
15042                }
15043
15044                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15045                    ProcessRecord app = mLruProcesses.get(i);
15046                    try {
15047                        if (app.thread != null) {
15048                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15049                                    + app.processName + " new config " + mConfiguration);
15050                            app.thread.scheduleConfigurationChanged(configCopy);
15051                        }
15052                    } catch (Exception e) {
15053                    }
15054                }
15055                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15056                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15057                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15058                        | Intent.FLAG_RECEIVER_FOREGROUND);
15059                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15060                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15061                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15062                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15063                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15064                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15065                    broadcastIntentLocked(null, null, intent,
15066                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15067                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15068                }
15069            }
15070        }
15071
15072        boolean kept = true;
15073        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15074        // mainStack is null during startup.
15075        if (mainStack != null) {
15076            if (changes != 0 && starting == null) {
15077                // If the configuration changed, and the caller is not already
15078                // in the process of starting an activity, then find the top
15079                // activity to check if its configuration needs to change.
15080                starting = mainStack.topRunningActivityLocked(null);
15081            }
15082
15083            if (starting != null) {
15084                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15085                // And we need to make sure at this point that all other activities
15086                // are made visible with the correct configuration.
15087                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15088            }
15089        }
15090
15091        if (values != null && mWindowManager != null) {
15092            mWindowManager.setNewConfiguration(mConfiguration);
15093        }
15094
15095        return kept;
15096    }
15097
15098    /**
15099     * Decide based on the configuration whether we should shouw the ANR,
15100     * crash, etc dialogs.  The idea is that if there is no affordnace to
15101     * press the on-screen buttons, we shouldn't show the dialog.
15102     *
15103     * A thought: SystemUI might also want to get told about this, the Power
15104     * dialog / global actions also might want different behaviors.
15105     */
15106    private static final boolean shouldShowDialogs(Configuration config) {
15107        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15108                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15109    }
15110
15111    /**
15112     * Save the locale.  You must be inside a synchronized (this) block.
15113     */
15114    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15115        if(isDiff) {
15116            SystemProperties.set("user.language", l.getLanguage());
15117            SystemProperties.set("user.region", l.getCountry());
15118        }
15119
15120        if(isPersist) {
15121            SystemProperties.set("persist.sys.language", l.getLanguage());
15122            SystemProperties.set("persist.sys.country", l.getCountry());
15123            SystemProperties.set("persist.sys.localevar", l.getVariant());
15124        }
15125    }
15126
15127    @Override
15128    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15129        ActivityRecord srec = ActivityRecord.forToken(token);
15130        return srec != null && srec.task.affinity != null &&
15131                srec.task.affinity.equals(destAffinity);
15132    }
15133
15134    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15135            Intent resultData) {
15136
15137        synchronized (this) {
15138            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15139            if (stack != null) {
15140                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15141            }
15142            return false;
15143        }
15144    }
15145
15146    public int getLaunchedFromUid(IBinder activityToken) {
15147        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15148        if (srec == null) {
15149            return -1;
15150        }
15151        return srec.launchedFromUid;
15152    }
15153
15154    public String getLaunchedFromPackage(IBinder activityToken) {
15155        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15156        if (srec == null) {
15157            return null;
15158        }
15159        return srec.launchedFromPackage;
15160    }
15161
15162    // =========================================================
15163    // LIFETIME MANAGEMENT
15164    // =========================================================
15165
15166    // Returns which broadcast queue the app is the current [or imminent] receiver
15167    // on, or 'null' if the app is not an active broadcast recipient.
15168    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15169        BroadcastRecord r = app.curReceiver;
15170        if (r != null) {
15171            return r.queue;
15172        }
15173
15174        // It's not the current receiver, but it might be starting up to become one
15175        synchronized (this) {
15176            for (BroadcastQueue queue : mBroadcastQueues) {
15177                r = queue.mPendingBroadcast;
15178                if (r != null && r.curApp == app) {
15179                    // found it; report which queue it's in
15180                    return queue;
15181                }
15182            }
15183        }
15184
15185        return null;
15186    }
15187
15188    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15189            boolean doingAll, long now) {
15190        if (mAdjSeq == app.adjSeq) {
15191            // This adjustment has already been computed.
15192            return app.curRawAdj;
15193        }
15194
15195        if (app.thread == null) {
15196            app.adjSeq = mAdjSeq;
15197            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15198            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15199            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15200        }
15201
15202        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15203        app.adjSource = null;
15204        app.adjTarget = null;
15205        app.empty = false;
15206        app.cached = false;
15207
15208        final int activitiesSize = app.activities.size();
15209
15210        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15211            // The max adjustment doesn't allow this app to be anything
15212            // below foreground, so it is not worth doing work for it.
15213            app.adjType = "fixed";
15214            app.adjSeq = mAdjSeq;
15215            app.curRawAdj = app.maxAdj;
15216            app.foregroundActivities = false;
15217            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15218            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15219            // System processes can do UI, and when they do we want to have
15220            // them trim their memory after the user leaves the UI.  To
15221            // facilitate this, here we need to determine whether or not it
15222            // is currently showing UI.
15223            app.systemNoUi = true;
15224            if (app == TOP_APP) {
15225                app.systemNoUi = false;
15226            } else if (activitiesSize > 0) {
15227                for (int j = 0; j < activitiesSize; j++) {
15228                    final ActivityRecord r = app.activities.get(j);
15229                    if (r.visible) {
15230                        app.systemNoUi = false;
15231                    }
15232                }
15233            }
15234            if (!app.systemNoUi) {
15235                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15236            }
15237            return (app.curAdj=app.maxAdj);
15238        }
15239
15240        app.systemNoUi = false;
15241
15242        // Determine the importance of the process, starting with most
15243        // important to least, and assign an appropriate OOM adjustment.
15244        int adj;
15245        int schedGroup;
15246        int procState;
15247        boolean foregroundActivities = false;
15248        BroadcastQueue queue;
15249        if (app == TOP_APP) {
15250            // The last app on the list is the foreground app.
15251            adj = ProcessList.FOREGROUND_APP_ADJ;
15252            schedGroup = Process.THREAD_GROUP_DEFAULT;
15253            app.adjType = "top-activity";
15254            foregroundActivities = true;
15255            procState = ActivityManager.PROCESS_STATE_TOP;
15256        } else if (app.instrumentationClass != null) {
15257            // Don't want to kill running instrumentation.
15258            adj = ProcessList.FOREGROUND_APP_ADJ;
15259            schedGroup = Process.THREAD_GROUP_DEFAULT;
15260            app.adjType = "instrumentation";
15261            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15262        } else if ((queue = isReceivingBroadcast(app)) != null) {
15263            // An app that is currently receiving a broadcast also
15264            // counts as being in the foreground for OOM killer purposes.
15265            // It's placed in a sched group based on the nature of the
15266            // broadcast as reflected by which queue it's active in.
15267            adj = ProcessList.FOREGROUND_APP_ADJ;
15268            schedGroup = (queue == mFgBroadcastQueue)
15269                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15270            app.adjType = "broadcast";
15271            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15272        } else if (app.executingServices.size() > 0) {
15273            // An app that is currently executing a service callback also
15274            // counts as being in the foreground.
15275            adj = ProcessList.FOREGROUND_APP_ADJ;
15276            schedGroup = app.execServicesFg ?
15277                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15278            app.adjType = "exec-service";
15279            procState = ActivityManager.PROCESS_STATE_SERVICE;
15280            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15281        } else {
15282            // As far as we know the process is empty.  We may change our mind later.
15283            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15284            // At this point we don't actually know the adjustment.  Use the cached adj
15285            // value that the caller wants us to.
15286            adj = cachedAdj;
15287            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15288            app.cached = true;
15289            app.empty = true;
15290            app.adjType = "cch-empty";
15291        }
15292
15293        // Examine all activities if not already foreground.
15294        if (!foregroundActivities && activitiesSize > 0) {
15295            for (int j = 0; j < activitiesSize; j++) {
15296                final ActivityRecord r = app.activities.get(j);
15297                if (r.app != app) {
15298                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15299                            + app + "?!?");
15300                    continue;
15301                }
15302                if (r.visible) {
15303                    // App has a visible activity; only upgrade adjustment.
15304                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15305                        adj = ProcessList.VISIBLE_APP_ADJ;
15306                        app.adjType = "visible";
15307                    }
15308                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15309                        procState = ActivityManager.PROCESS_STATE_TOP;
15310                    }
15311                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15312                    app.cached = false;
15313                    app.empty = false;
15314                    foregroundActivities = true;
15315                    break;
15316                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15317                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15318                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15319                        app.adjType = "pausing";
15320                    }
15321                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15322                        procState = ActivityManager.PROCESS_STATE_TOP;
15323                    }
15324                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15325                    app.cached = false;
15326                    app.empty = false;
15327                    foregroundActivities = true;
15328                } else if (r.state == ActivityState.STOPPING) {
15329                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15330                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15331                        app.adjType = "stopping";
15332                    }
15333                    // For the process state, we will at this point consider the
15334                    // process to be cached.  It will be cached either as an activity
15335                    // or empty depending on whether the activity is finishing.  We do
15336                    // this so that we can treat the process as cached for purposes of
15337                    // memory trimming (determing current memory level, trim command to
15338                    // send to process) since there can be an arbitrary number of stopping
15339                    // processes and they should soon all go into the cached state.
15340                    if (!r.finishing) {
15341                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15342                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15343                        }
15344                    }
15345                    app.cached = false;
15346                    app.empty = false;
15347                    foregroundActivities = true;
15348                } else {
15349                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15350                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15351                        app.adjType = "cch-act";
15352                    }
15353                }
15354            }
15355        }
15356
15357        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15358            if (app.foregroundServices) {
15359                // The user is aware of this app, so make it visible.
15360                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15361                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15362                app.cached = false;
15363                app.adjType = "fg-service";
15364                schedGroup = Process.THREAD_GROUP_DEFAULT;
15365            } else if (app.forcingToForeground != null) {
15366                // The user is aware of this app, so make it visible.
15367                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15368                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15369                app.cached = false;
15370                app.adjType = "force-fg";
15371                app.adjSource = app.forcingToForeground;
15372                schedGroup = Process.THREAD_GROUP_DEFAULT;
15373            }
15374        }
15375
15376        if (app == mHeavyWeightProcess) {
15377            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15378                // We don't want to kill the current heavy-weight process.
15379                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15380                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15381                app.cached = false;
15382                app.adjType = "heavy";
15383            }
15384            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15385                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15386            }
15387        }
15388
15389        if (app == mHomeProcess) {
15390            if (adj > ProcessList.HOME_APP_ADJ) {
15391                // This process is hosting what we currently consider to be the
15392                // home app, so we don't want to let it go into the background.
15393                adj = ProcessList.HOME_APP_ADJ;
15394                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15395                app.cached = false;
15396                app.adjType = "home";
15397            }
15398            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15399                procState = ActivityManager.PROCESS_STATE_HOME;
15400            }
15401        }
15402
15403        if (app == mPreviousProcess && app.activities.size() > 0) {
15404            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15405                // This was the previous process that showed UI to the user.
15406                // We want to try to keep it around more aggressively, to give
15407                // a good experience around switching between two apps.
15408                adj = ProcessList.PREVIOUS_APP_ADJ;
15409                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15410                app.cached = false;
15411                app.adjType = "previous";
15412            }
15413            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15414                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15415            }
15416        }
15417
15418        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15419                + " reason=" + app.adjType);
15420
15421        // By default, we use the computed adjustment.  It may be changed if
15422        // there are applications dependent on our services or providers, but
15423        // this gives us a baseline and makes sure we don't get into an
15424        // infinite recursion.
15425        app.adjSeq = mAdjSeq;
15426        app.curRawAdj = adj;
15427        app.hasStartedServices = false;
15428
15429        if (mBackupTarget != null && app == mBackupTarget.app) {
15430            // If possible we want to avoid killing apps while they're being backed up
15431            if (adj > ProcessList.BACKUP_APP_ADJ) {
15432                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15433                adj = ProcessList.BACKUP_APP_ADJ;
15434                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15435                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15436                }
15437                app.adjType = "backup";
15438                app.cached = false;
15439            }
15440            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15441                procState = ActivityManager.PROCESS_STATE_BACKUP;
15442            }
15443        }
15444
15445        boolean mayBeTop = false;
15446
15447        for (int is = app.services.size()-1;
15448                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15449                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15450                        || procState > ActivityManager.PROCESS_STATE_TOP);
15451                is--) {
15452            ServiceRecord s = app.services.valueAt(is);
15453            if (s.startRequested) {
15454                app.hasStartedServices = true;
15455                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15456                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15457                }
15458                if (app.hasShownUi && app != mHomeProcess) {
15459                    // If this process has shown some UI, let it immediately
15460                    // go to the LRU list because it may be pretty heavy with
15461                    // UI stuff.  We'll tag it with a label just to help
15462                    // debug and understand what is going on.
15463                    if (adj > ProcessList.SERVICE_ADJ) {
15464                        app.adjType = "cch-started-ui-services";
15465                    }
15466                } else {
15467                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15468                        // This service has seen some activity within
15469                        // recent memory, so we will keep its process ahead
15470                        // of the background processes.
15471                        if (adj > ProcessList.SERVICE_ADJ) {
15472                            adj = ProcessList.SERVICE_ADJ;
15473                            app.adjType = "started-services";
15474                            app.cached = false;
15475                        }
15476                    }
15477                    // If we have let the service slide into the background
15478                    // state, still have some text describing what it is doing
15479                    // even though the service no longer has an impact.
15480                    if (adj > ProcessList.SERVICE_ADJ) {
15481                        app.adjType = "cch-started-services";
15482                    }
15483                }
15484            }
15485            for (int conni = s.connections.size()-1;
15486                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15487                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15488                            || procState > ActivityManager.PROCESS_STATE_TOP);
15489                    conni--) {
15490                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15491                for (int i = 0;
15492                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15493                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15494                                || procState > ActivityManager.PROCESS_STATE_TOP);
15495                        i++) {
15496                    // XXX should compute this based on the max of
15497                    // all connected clients.
15498                    ConnectionRecord cr = clist.get(i);
15499                    if (cr.binding.client == app) {
15500                        // Binding to ourself is not interesting.
15501                        continue;
15502                    }
15503                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15504                        ProcessRecord client = cr.binding.client;
15505                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15506                                TOP_APP, doingAll, now);
15507                        int clientProcState = client.curProcState;
15508                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15509                            // If the other app is cached for any reason, for purposes here
15510                            // we are going to consider it empty.  The specific cached state
15511                            // doesn't propagate except under certain conditions.
15512                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15513                        }
15514                        String adjType = null;
15515                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15516                            // Not doing bind OOM management, so treat
15517                            // this guy more like a started service.
15518                            if (app.hasShownUi && app != mHomeProcess) {
15519                                // If this process has shown some UI, let it immediately
15520                                // go to the LRU list because it may be pretty heavy with
15521                                // UI stuff.  We'll tag it with a label just to help
15522                                // debug and understand what is going on.
15523                                if (adj > clientAdj) {
15524                                    adjType = "cch-bound-ui-services";
15525                                }
15526                                app.cached = false;
15527                                clientAdj = adj;
15528                                clientProcState = procState;
15529                            } else {
15530                                if (now >= (s.lastActivity
15531                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15532                                    // This service has not seen activity within
15533                                    // recent memory, so allow it to drop to the
15534                                    // LRU list if there is no other reason to keep
15535                                    // it around.  We'll also tag it with a label just
15536                                    // to help debug and undertand what is going on.
15537                                    if (adj > clientAdj) {
15538                                        adjType = "cch-bound-services";
15539                                    }
15540                                    clientAdj = adj;
15541                                }
15542                            }
15543                        }
15544                        if (adj > clientAdj) {
15545                            // If this process has recently shown UI, and
15546                            // the process that is binding to it is less
15547                            // important than being visible, then we don't
15548                            // care about the binding as much as we care
15549                            // about letting this process get into the LRU
15550                            // list to be killed and restarted if needed for
15551                            // memory.
15552                            if (app.hasShownUi && app != mHomeProcess
15553                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15554                                adjType = "cch-bound-ui-services";
15555                            } else {
15556                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15557                                        |Context.BIND_IMPORTANT)) != 0) {
15558                                    adj = clientAdj;
15559                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15560                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15561                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15562                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15563                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15564                                    adj = clientAdj;
15565                                } else {
15566                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15567                                        adj = ProcessList.VISIBLE_APP_ADJ;
15568                                    }
15569                                }
15570                                if (!client.cached) {
15571                                    app.cached = false;
15572                                }
15573                                adjType = "service";
15574                            }
15575                        }
15576                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15577                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15578                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15579                            }
15580                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15581                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15582                                    // Special handling of clients who are in the top state.
15583                                    // We *may* want to consider this process to be in the
15584                                    // top state as well, but only if there is not another
15585                                    // reason for it to be running.  Being on the top is a
15586                                    // special state, meaning you are specifically running
15587                                    // for the current top app.  If the process is already
15588                                    // running in the background for some other reason, it
15589                                    // is more important to continue considering it to be
15590                                    // in the background state.
15591                                    mayBeTop = true;
15592                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15593                                } else {
15594                                    // Special handling for above-top states (persistent
15595                                    // processes).  These should not bring the current process
15596                                    // into the top state, since they are not on top.  Instead
15597                                    // give them the best state after that.
15598                                    clientProcState =
15599                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15600                                }
15601                            }
15602                        } else {
15603                            if (clientProcState <
15604                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15605                                clientProcState =
15606                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15607                            }
15608                        }
15609                        if (procState > clientProcState) {
15610                            procState = clientProcState;
15611                        }
15612                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15613                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15614                            app.pendingUiClean = true;
15615                        }
15616                        if (adjType != null) {
15617                            app.adjType = adjType;
15618                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15619                                    .REASON_SERVICE_IN_USE;
15620                            app.adjSource = cr.binding.client;
15621                            app.adjSourceProcState = clientProcState;
15622                            app.adjTarget = s.name;
15623                        }
15624                    }
15625                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15626                        app.treatLikeActivity = true;
15627                    }
15628                    final ActivityRecord a = cr.activity;
15629                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15630                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15631                                (a.visible || a.state == ActivityState.RESUMED
15632                                 || a.state == ActivityState.PAUSING)) {
15633                            adj = ProcessList.FOREGROUND_APP_ADJ;
15634                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15635                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15636                            }
15637                            app.cached = false;
15638                            app.adjType = "service";
15639                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15640                                    .REASON_SERVICE_IN_USE;
15641                            app.adjSource = a;
15642                            app.adjSourceProcState = procState;
15643                            app.adjTarget = s.name;
15644                        }
15645                    }
15646                }
15647            }
15648        }
15649
15650        for (int provi = app.pubProviders.size()-1;
15651                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15652                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15653                        || procState > ActivityManager.PROCESS_STATE_TOP);
15654                provi--) {
15655            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15656            for (int i = cpr.connections.size()-1;
15657                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15658                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15659                            || procState > ActivityManager.PROCESS_STATE_TOP);
15660                    i--) {
15661                ContentProviderConnection conn = cpr.connections.get(i);
15662                ProcessRecord client = conn.client;
15663                if (client == app) {
15664                    // Being our own client is not interesting.
15665                    continue;
15666                }
15667                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15668                int clientProcState = client.curProcState;
15669                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15670                    // If the other app is cached for any reason, for purposes here
15671                    // we are going to consider it empty.
15672                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15673                }
15674                if (adj > clientAdj) {
15675                    if (app.hasShownUi && app != mHomeProcess
15676                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15677                        app.adjType = "cch-ui-provider";
15678                    } else {
15679                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15680                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15681                        app.adjType = "provider";
15682                    }
15683                    app.cached &= client.cached;
15684                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15685                            .REASON_PROVIDER_IN_USE;
15686                    app.adjSource = client;
15687                    app.adjSourceProcState = clientProcState;
15688                    app.adjTarget = cpr.name;
15689                }
15690                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15691                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15692                        // Special handling of clients who are in the top state.
15693                        // We *may* want to consider this process to be in the
15694                        // top state as well, but only if there is not another
15695                        // reason for it to be running.  Being on the top is a
15696                        // special state, meaning you are specifically running
15697                        // for the current top app.  If the process is already
15698                        // running in the background for some other reason, it
15699                        // is more important to continue considering it to be
15700                        // in the background state.
15701                        mayBeTop = true;
15702                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15703                    } else {
15704                        // Special handling for above-top states (persistent
15705                        // processes).  These should not bring the current process
15706                        // into the top state, since they are not on top.  Instead
15707                        // give them the best state after that.
15708                        clientProcState =
15709                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15710                    }
15711                }
15712                if (procState > clientProcState) {
15713                    procState = clientProcState;
15714                }
15715                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15716                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15717                }
15718            }
15719            // If the provider has external (non-framework) process
15720            // dependencies, ensure that its adjustment is at least
15721            // FOREGROUND_APP_ADJ.
15722            if (cpr.hasExternalProcessHandles()) {
15723                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15724                    adj = ProcessList.FOREGROUND_APP_ADJ;
15725                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15726                    app.cached = false;
15727                    app.adjType = "provider";
15728                    app.adjTarget = cpr.name;
15729                }
15730                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15731                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15732                }
15733            }
15734        }
15735
15736        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15737            // A client of one of our services or providers is in the top state.  We
15738            // *may* want to be in the top state, but not if we are already running in
15739            // the background for some other reason.  For the decision here, we are going
15740            // to pick out a few specific states that we want to remain in when a client
15741            // is top (states that tend to be longer-term) and otherwise allow it to go
15742            // to the top state.
15743            switch (procState) {
15744                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15745                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15746                case ActivityManager.PROCESS_STATE_SERVICE:
15747                    // These all are longer-term states, so pull them up to the top
15748                    // of the background states, but not all the way to the top state.
15749                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15750                    break;
15751                default:
15752                    // Otherwise, top is a better choice, so take it.
15753                    procState = ActivityManager.PROCESS_STATE_TOP;
15754                    break;
15755            }
15756        }
15757
15758        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15759            if (app.hasClientActivities) {
15760                // This is a cached process, but with client activities.  Mark it so.
15761                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15762                app.adjType = "cch-client-act";
15763            } else if (app.treatLikeActivity) {
15764                // This is a cached process, but somebody wants us to treat it like it has
15765                // an activity, okay!
15766                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15767                app.adjType = "cch-as-act";
15768            }
15769        }
15770
15771        if (adj == ProcessList.SERVICE_ADJ) {
15772            if (doingAll) {
15773                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15774                mNewNumServiceProcs++;
15775                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15776                if (!app.serviceb) {
15777                    // This service isn't far enough down on the LRU list to
15778                    // normally be a B service, but if we are low on RAM and it
15779                    // is large we want to force it down since we would prefer to
15780                    // keep launcher over it.
15781                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15782                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15783                        app.serviceHighRam = true;
15784                        app.serviceb = true;
15785                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15786                    } else {
15787                        mNewNumAServiceProcs++;
15788                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15789                    }
15790                } else {
15791                    app.serviceHighRam = false;
15792                }
15793            }
15794            if (app.serviceb) {
15795                adj = ProcessList.SERVICE_B_ADJ;
15796            }
15797        }
15798
15799        app.curRawAdj = adj;
15800
15801        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15802        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15803        if (adj > app.maxAdj) {
15804            adj = app.maxAdj;
15805            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15806                schedGroup = Process.THREAD_GROUP_DEFAULT;
15807            }
15808        }
15809
15810        // Do final modification to adj.  Everything we do between here and applying
15811        // the final setAdj must be done in this function, because we will also use
15812        // it when computing the final cached adj later.  Note that we don't need to
15813        // worry about this for max adj above, since max adj will always be used to
15814        // keep it out of the cached vaues.
15815        app.curAdj = app.modifyRawOomAdj(adj);
15816        app.curSchedGroup = schedGroup;
15817        app.curProcState = procState;
15818        app.foregroundActivities = foregroundActivities;
15819
15820        return app.curRawAdj;
15821    }
15822
15823    /**
15824     * Schedule PSS collection of a process.
15825     */
15826    void requestPssLocked(ProcessRecord proc, int procState) {
15827        if (mPendingPssProcesses.contains(proc)) {
15828            return;
15829        }
15830        if (mPendingPssProcesses.size() == 0) {
15831            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15832        }
15833        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15834        proc.pssProcState = procState;
15835        mPendingPssProcesses.add(proc);
15836    }
15837
15838    /**
15839     * Schedule PSS collection of all processes.
15840     */
15841    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15842        if (!always) {
15843            if (now < (mLastFullPssTime +
15844                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15845                return;
15846            }
15847        }
15848        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15849        mLastFullPssTime = now;
15850        mFullPssPending = true;
15851        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15852        mPendingPssProcesses.clear();
15853        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15854            ProcessRecord app = mLruProcesses.get(i);
15855            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15856                app.pssProcState = app.setProcState;
15857                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15858                        isSleeping(), now);
15859                mPendingPssProcesses.add(app);
15860            }
15861        }
15862        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15863    }
15864
15865    /**
15866     * Ask a given process to GC right now.
15867     */
15868    final void performAppGcLocked(ProcessRecord app) {
15869        try {
15870            app.lastRequestedGc = SystemClock.uptimeMillis();
15871            if (app.thread != null) {
15872                if (app.reportLowMemory) {
15873                    app.reportLowMemory = false;
15874                    app.thread.scheduleLowMemory();
15875                } else {
15876                    app.thread.processInBackground();
15877                }
15878            }
15879        } catch (Exception e) {
15880            // whatever.
15881        }
15882    }
15883
15884    /**
15885     * Returns true if things are idle enough to perform GCs.
15886     */
15887    private final boolean canGcNowLocked() {
15888        boolean processingBroadcasts = false;
15889        for (BroadcastQueue q : mBroadcastQueues) {
15890            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15891                processingBroadcasts = true;
15892            }
15893        }
15894        return !processingBroadcasts
15895                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15896    }
15897
15898    /**
15899     * Perform GCs on all processes that are waiting for it, but only
15900     * if things are idle.
15901     */
15902    final void performAppGcsLocked() {
15903        final int N = mProcessesToGc.size();
15904        if (N <= 0) {
15905            return;
15906        }
15907        if (canGcNowLocked()) {
15908            while (mProcessesToGc.size() > 0) {
15909                ProcessRecord proc = mProcessesToGc.remove(0);
15910                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15911                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15912                            <= SystemClock.uptimeMillis()) {
15913                        // To avoid spamming the system, we will GC processes one
15914                        // at a time, waiting a few seconds between each.
15915                        performAppGcLocked(proc);
15916                        scheduleAppGcsLocked();
15917                        return;
15918                    } else {
15919                        // It hasn't been long enough since we last GCed this
15920                        // process...  put it in the list to wait for its time.
15921                        addProcessToGcListLocked(proc);
15922                        break;
15923                    }
15924                }
15925            }
15926
15927            scheduleAppGcsLocked();
15928        }
15929    }
15930
15931    /**
15932     * If all looks good, perform GCs on all processes waiting for them.
15933     */
15934    final void performAppGcsIfAppropriateLocked() {
15935        if (canGcNowLocked()) {
15936            performAppGcsLocked();
15937            return;
15938        }
15939        // Still not idle, wait some more.
15940        scheduleAppGcsLocked();
15941    }
15942
15943    /**
15944     * Schedule the execution of all pending app GCs.
15945     */
15946    final void scheduleAppGcsLocked() {
15947        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15948
15949        if (mProcessesToGc.size() > 0) {
15950            // Schedule a GC for the time to the next process.
15951            ProcessRecord proc = mProcessesToGc.get(0);
15952            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15953
15954            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15955            long now = SystemClock.uptimeMillis();
15956            if (when < (now+GC_TIMEOUT)) {
15957                when = now + GC_TIMEOUT;
15958            }
15959            mHandler.sendMessageAtTime(msg, when);
15960        }
15961    }
15962
15963    /**
15964     * Add a process to the array of processes waiting to be GCed.  Keeps the
15965     * list in sorted order by the last GC time.  The process can't already be
15966     * on the list.
15967     */
15968    final void addProcessToGcListLocked(ProcessRecord proc) {
15969        boolean added = false;
15970        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15971            if (mProcessesToGc.get(i).lastRequestedGc <
15972                    proc.lastRequestedGc) {
15973                added = true;
15974                mProcessesToGc.add(i+1, proc);
15975                break;
15976            }
15977        }
15978        if (!added) {
15979            mProcessesToGc.add(0, proc);
15980        }
15981    }
15982
15983    /**
15984     * Set up to ask a process to GC itself.  This will either do it
15985     * immediately, or put it on the list of processes to gc the next
15986     * time things are idle.
15987     */
15988    final void scheduleAppGcLocked(ProcessRecord app) {
15989        long now = SystemClock.uptimeMillis();
15990        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15991            return;
15992        }
15993        if (!mProcessesToGc.contains(app)) {
15994            addProcessToGcListLocked(app);
15995            scheduleAppGcsLocked();
15996        }
15997    }
15998
15999    final void checkExcessivePowerUsageLocked(boolean doKills) {
16000        updateCpuStatsNow();
16001
16002        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16003        boolean doWakeKills = doKills;
16004        boolean doCpuKills = doKills;
16005        if (mLastPowerCheckRealtime == 0) {
16006            doWakeKills = false;
16007        }
16008        if (mLastPowerCheckUptime == 0) {
16009            doCpuKills = false;
16010        }
16011        if (stats.isScreenOn()) {
16012            doWakeKills = false;
16013        }
16014        final long curRealtime = SystemClock.elapsedRealtime();
16015        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16016        final long curUptime = SystemClock.uptimeMillis();
16017        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16018        mLastPowerCheckRealtime = curRealtime;
16019        mLastPowerCheckUptime = curUptime;
16020        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16021            doWakeKills = false;
16022        }
16023        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16024            doCpuKills = false;
16025        }
16026        int i = mLruProcesses.size();
16027        while (i > 0) {
16028            i--;
16029            ProcessRecord app = mLruProcesses.get(i);
16030            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16031                long wtime;
16032                synchronized (stats) {
16033                    wtime = stats.getProcessWakeTime(app.info.uid,
16034                            app.pid, curRealtime);
16035                }
16036                long wtimeUsed = wtime - app.lastWakeTime;
16037                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16038                if (DEBUG_POWER) {
16039                    StringBuilder sb = new StringBuilder(128);
16040                    sb.append("Wake for ");
16041                    app.toShortString(sb);
16042                    sb.append(": over ");
16043                    TimeUtils.formatDuration(realtimeSince, sb);
16044                    sb.append(" used ");
16045                    TimeUtils.formatDuration(wtimeUsed, sb);
16046                    sb.append(" (");
16047                    sb.append((wtimeUsed*100)/realtimeSince);
16048                    sb.append("%)");
16049                    Slog.i(TAG, sb.toString());
16050                    sb.setLength(0);
16051                    sb.append("CPU for ");
16052                    app.toShortString(sb);
16053                    sb.append(": over ");
16054                    TimeUtils.formatDuration(uptimeSince, sb);
16055                    sb.append(" used ");
16056                    TimeUtils.formatDuration(cputimeUsed, sb);
16057                    sb.append(" (");
16058                    sb.append((cputimeUsed*100)/uptimeSince);
16059                    sb.append("%)");
16060                    Slog.i(TAG, sb.toString());
16061                }
16062                // If a process has held a wake lock for more
16063                // than 50% of the time during this period,
16064                // that sounds bad.  Kill!
16065                if (doWakeKills && realtimeSince > 0
16066                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16067                    synchronized (stats) {
16068                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16069                                realtimeSince, wtimeUsed);
16070                    }
16071                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16072                            + " during " + realtimeSince);
16073                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16074                } else if (doCpuKills && uptimeSince > 0
16075                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16076                    synchronized (stats) {
16077                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16078                                uptimeSince, cputimeUsed);
16079                    }
16080                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16081                            + " during " + uptimeSince);
16082                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16083                } else {
16084                    app.lastWakeTime = wtime;
16085                    app.lastCpuTime = app.curCpuTime;
16086                }
16087            }
16088        }
16089    }
16090
16091    private final boolean applyOomAdjLocked(ProcessRecord app,
16092            ProcessRecord TOP_APP, boolean doingAll, long now) {
16093        boolean success = true;
16094
16095        if (app.curRawAdj != app.setRawAdj) {
16096            app.setRawAdj = app.curRawAdj;
16097        }
16098
16099        int changes = 0;
16100
16101        if (app.curAdj != app.setAdj) {
16102            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16103            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16104                TAG, "Set " + app.pid + " " + app.processName +
16105                " adj " + app.curAdj + ": " + app.adjType);
16106            app.setAdj = app.curAdj;
16107        }
16108
16109        if (app.setSchedGroup != app.curSchedGroup) {
16110            app.setSchedGroup = app.curSchedGroup;
16111            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16112                    "Setting process group of " + app.processName
16113                    + " to " + app.curSchedGroup);
16114            if (app.waitingToKill != null &&
16115                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16116                killUnneededProcessLocked(app, app.waitingToKill);
16117                success = false;
16118            } else {
16119                if (true) {
16120                    long oldId = Binder.clearCallingIdentity();
16121                    try {
16122                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16123                    } catch (Exception e) {
16124                        Slog.w(TAG, "Failed setting process group of " + app.pid
16125                                + " to " + app.curSchedGroup);
16126                        e.printStackTrace();
16127                    } finally {
16128                        Binder.restoreCallingIdentity(oldId);
16129                    }
16130                } else {
16131                    if (app.thread != null) {
16132                        try {
16133                            app.thread.setSchedulingGroup(app.curSchedGroup);
16134                        } catch (RemoteException e) {
16135                        }
16136                    }
16137                }
16138                Process.setSwappiness(app.pid,
16139                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16140            }
16141        }
16142        if (app.repForegroundActivities != app.foregroundActivities) {
16143            app.repForegroundActivities = app.foregroundActivities;
16144            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16145        }
16146        if (app.repProcState != app.curProcState) {
16147            app.repProcState = app.curProcState;
16148            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16149            if (app.thread != null) {
16150                try {
16151                    if (false) {
16152                        //RuntimeException h = new RuntimeException("here");
16153                        Slog.i(TAG, "Sending new process state " + app.repProcState
16154                                + " to " + app /*, h*/);
16155                    }
16156                    app.thread.setProcessState(app.repProcState);
16157                } catch (RemoteException e) {
16158                }
16159            }
16160        }
16161        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16162                app.setProcState)) {
16163            app.lastStateTime = now;
16164            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16165                    isSleeping(), now);
16166            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16167                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16168                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16169                    + (app.nextPssTime-now) + ": " + app);
16170        } else {
16171            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16172                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16173                requestPssLocked(app, app.setProcState);
16174                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16175                        isSleeping(), now);
16176            } else if (false && DEBUG_PSS) {
16177                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16178            }
16179        }
16180        if (app.setProcState != app.curProcState) {
16181            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16182                    "Proc state change of " + app.processName
16183                    + " to " + app.curProcState);
16184            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16185            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16186            if (setImportant && !curImportant) {
16187                // This app is no longer something we consider important enough to allow to
16188                // use arbitrary amounts of battery power.  Note
16189                // its current wake lock time to later know to kill it if
16190                // it is not behaving well.
16191                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16192                synchronized (stats) {
16193                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16194                            app.pid, SystemClock.elapsedRealtime());
16195                }
16196                app.lastCpuTime = app.curCpuTime;
16197
16198            }
16199            app.setProcState = app.curProcState;
16200            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16201                app.notCachedSinceIdle = false;
16202            }
16203            if (!doingAll) {
16204                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16205            } else {
16206                app.procStateChanged = true;
16207            }
16208        }
16209
16210        if (changes != 0) {
16211            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16212            int i = mPendingProcessChanges.size()-1;
16213            ProcessChangeItem item = null;
16214            while (i >= 0) {
16215                item = mPendingProcessChanges.get(i);
16216                if (item.pid == app.pid) {
16217                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16218                    break;
16219                }
16220                i--;
16221            }
16222            if (i < 0) {
16223                // No existing item in pending changes; need a new one.
16224                final int NA = mAvailProcessChanges.size();
16225                if (NA > 0) {
16226                    item = mAvailProcessChanges.remove(NA-1);
16227                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16228                } else {
16229                    item = new ProcessChangeItem();
16230                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16231                }
16232                item.changes = 0;
16233                item.pid = app.pid;
16234                item.uid = app.info.uid;
16235                if (mPendingProcessChanges.size() == 0) {
16236                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16237                            "*** Enqueueing dispatch processes changed!");
16238                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16239                }
16240                mPendingProcessChanges.add(item);
16241            }
16242            item.changes |= changes;
16243            item.processState = app.repProcState;
16244            item.foregroundActivities = app.repForegroundActivities;
16245            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16246                    + Integer.toHexString(System.identityHashCode(item))
16247                    + " " + app.toShortString() + ": changes=" + item.changes
16248                    + " procState=" + item.processState
16249                    + " foreground=" + item.foregroundActivities
16250                    + " type=" + app.adjType + " source=" + app.adjSource
16251                    + " target=" + app.adjTarget);
16252        }
16253
16254        return success;
16255    }
16256
16257    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16258        if (proc.thread != null) {
16259            if (proc.baseProcessTracker != null) {
16260                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16261            }
16262            if (proc.repProcState >= 0) {
16263                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16264                        proc.repProcState);
16265            }
16266        }
16267    }
16268
16269    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16270            ProcessRecord TOP_APP, boolean doingAll, long now) {
16271        if (app.thread == null) {
16272            return false;
16273        }
16274
16275        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16276
16277        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16278    }
16279
16280    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16281            boolean oomAdj) {
16282        if (isForeground != proc.foregroundServices) {
16283            proc.foregroundServices = isForeground;
16284            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16285                    proc.info.uid);
16286            if (isForeground) {
16287                if (curProcs == null) {
16288                    curProcs = new ArrayList<ProcessRecord>();
16289                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16290                }
16291                if (!curProcs.contains(proc)) {
16292                    curProcs.add(proc);
16293                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16294                            proc.info.packageName, proc.info.uid);
16295                }
16296            } else {
16297                if (curProcs != null) {
16298                    if (curProcs.remove(proc)) {
16299                        mBatteryStatsService.noteEvent(
16300                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16301                                proc.info.packageName, proc.info.uid);
16302                        if (curProcs.size() <= 0) {
16303                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16304                        }
16305                    }
16306                }
16307            }
16308            if (oomAdj) {
16309                updateOomAdjLocked();
16310            }
16311        }
16312    }
16313
16314    private final ActivityRecord resumedAppLocked() {
16315        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16316        String pkg;
16317        int uid;
16318        if (act != null) {
16319            pkg = act.packageName;
16320            uid = act.info.applicationInfo.uid;
16321        } else {
16322            pkg = null;
16323            uid = -1;
16324        }
16325        // Has the UID or resumed package name changed?
16326        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16327                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16328            if (mCurResumedPackage != null) {
16329                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16330                        mCurResumedPackage, mCurResumedUid);
16331            }
16332            mCurResumedPackage = pkg;
16333            mCurResumedUid = uid;
16334            if (mCurResumedPackage != null) {
16335                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16336                        mCurResumedPackage, mCurResumedUid);
16337            }
16338        }
16339        return act;
16340    }
16341
16342    final boolean updateOomAdjLocked(ProcessRecord app) {
16343        final ActivityRecord TOP_ACT = resumedAppLocked();
16344        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16345        final boolean wasCached = app.cached;
16346
16347        mAdjSeq++;
16348
16349        // This is the desired cached adjusment we want to tell it to use.
16350        // If our app is currently cached, we know it, and that is it.  Otherwise,
16351        // we don't know it yet, and it needs to now be cached we will then
16352        // need to do a complete oom adj.
16353        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16354                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16355        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16356                SystemClock.uptimeMillis());
16357        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16358            // Changed to/from cached state, so apps after it in the LRU
16359            // list may also be changed.
16360            updateOomAdjLocked();
16361        }
16362        return success;
16363    }
16364
16365    final void updateOomAdjLocked() {
16366        final ActivityRecord TOP_ACT = resumedAppLocked();
16367        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16368        final long now = SystemClock.uptimeMillis();
16369        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16370        final int N = mLruProcesses.size();
16371
16372        if (false) {
16373            RuntimeException e = new RuntimeException();
16374            e.fillInStackTrace();
16375            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16376        }
16377
16378        mAdjSeq++;
16379        mNewNumServiceProcs = 0;
16380        mNewNumAServiceProcs = 0;
16381
16382        final int emptyProcessLimit;
16383        final int cachedProcessLimit;
16384        if (mProcessLimit <= 0) {
16385            emptyProcessLimit = cachedProcessLimit = 0;
16386        } else if (mProcessLimit == 1) {
16387            emptyProcessLimit = 1;
16388            cachedProcessLimit = 0;
16389        } else {
16390            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16391            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16392        }
16393
16394        // Let's determine how many processes we have running vs.
16395        // how many slots we have for background processes; we may want
16396        // to put multiple processes in a slot of there are enough of
16397        // them.
16398        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16399                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16400        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16401        if (numEmptyProcs > cachedProcessLimit) {
16402            // If there are more empty processes than our limit on cached
16403            // processes, then use the cached process limit for the factor.
16404            // This ensures that the really old empty processes get pushed
16405            // down to the bottom, so if we are running low on memory we will
16406            // have a better chance at keeping around more cached processes
16407            // instead of a gazillion empty processes.
16408            numEmptyProcs = cachedProcessLimit;
16409        }
16410        int emptyFactor = numEmptyProcs/numSlots;
16411        if (emptyFactor < 1) emptyFactor = 1;
16412        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16413        if (cachedFactor < 1) cachedFactor = 1;
16414        int stepCached = 0;
16415        int stepEmpty = 0;
16416        int numCached = 0;
16417        int numEmpty = 0;
16418        int numTrimming = 0;
16419
16420        mNumNonCachedProcs = 0;
16421        mNumCachedHiddenProcs = 0;
16422
16423        // First update the OOM adjustment for each of the
16424        // application processes based on their current state.
16425        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16426        int nextCachedAdj = curCachedAdj+1;
16427        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16428        int nextEmptyAdj = curEmptyAdj+2;
16429        for (int i=N-1; i>=0; i--) {
16430            ProcessRecord app = mLruProcesses.get(i);
16431            if (!app.killedByAm && app.thread != null) {
16432                app.procStateChanged = false;
16433                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16434
16435                // If we haven't yet assigned the final cached adj
16436                // to the process, do that now.
16437                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16438                    switch (app.curProcState) {
16439                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16440                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16441                            // This process is a cached process holding activities...
16442                            // assign it the next cached value for that type, and then
16443                            // step that cached level.
16444                            app.curRawAdj = curCachedAdj;
16445                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16446                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16447                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16448                                    + ")");
16449                            if (curCachedAdj != nextCachedAdj) {
16450                                stepCached++;
16451                                if (stepCached >= cachedFactor) {
16452                                    stepCached = 0;
16453                                    curCachedAdj = nextCachedAdj;
16454                                    nextCachedAdj += 2;
16455                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16456                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16457                                    }
16458                                }
16459                            }
16460                            break;
16461                        default:
16462                            // For everything else, assign next empty cached process
16463                            // level and bump that up.  Note that this means that
16464                            // long-running services that have dropped down to the
16465                            // cached level will be treated as empty (since their process
16466                            // state is still as a service), which is what we want.
16467                            app.curRawAdj = curEmptyAdj;
16468                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16469                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16470                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16471                                    + ")");
16472                            if (curEmptyAdj != nextEmptyAdj) {
16473                                stepEmpty++;
16474                                if (stepEmpty >= emptyFactor) {
16475                                    stepEmpty = 0;
16476                                    curEmptyAdj = nextEmptyAdj;
16477                                    nextEmptyAdj += 2;
16478                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16479                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16480                                    }
16481                                }
16482                            }
16483                            break;
16484                    }
16485                }
16486
16487                applyOomAdjLocked(app, TOP_APP, true, now);
16488
16489                // Count the number of process types.
16490                switch (app.curProcState) {
16491                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16492                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16493                        mNumCachedHiddenProcs++;
16494                        numCached++;
16495                        if (numCached > cachedProcessLimit) {
16496                            killUnneededProcessLocked(app, "cached #" + numCached);
16497                        }
16498                        break;
16499                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16500                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16501                                && app.lastActivityTime < oldTime) {
16502                            killUnneededProcessLocked(app, "empty for "
16503                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16504                                    / 1000) + "s");
16505                        } else {
16506                            numEmpty++;
16507                            if (numEmpty > emptyProcessLimit) {
16508                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16509                            }
16510                        }
16511                        break;
16512                    default:
16513                        mNumNonCachedProcs++;
16514                        break;
16515                }
16516
16517                if (app.isolated && app.services.size() <= 0) {
16518                    // If this is an isolated process, and there are no
16519                    // services running in it, then the process is no longer
16520                    // needed.  We agressively kill these because we can by
16521                    // definition not re-use the same process again, and it is
16522                    // good to avoid having whatever code was running in them
16523                    // left sitting around after no longer needed.
16524                    killUnneededProcessLocked(app, "isolated not needed");
16525                }
16526
16527                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16528                        && !app.killedByAm) {
16529                    numTrimming++;
16530                }
16531            }
16532        }
16533
16534        mNumServiceProcs = mNewNumServiceProcs;
16535
16536        // Now determine the memory trimming level of background processes.
16537        // Unfortunately we need to start at the back of the list to do this
16538        // properly.  We only do this if the number of background apps we
16539        // are managing to keep around is less than half the maximum we desire;
16540        // if we are keeping a good number around, we'll let them use whatever
16541        // memory they want.
16542        final int numCachedAndEmpty = numCached + numEmpty;
16543        int memFactor;
16544        if (numCached <= ProcessList.TRIM_CACHED_APPS
16545                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16546            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16547                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16548            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16549                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16550            } else {
16551                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16552            }
16553        } else {
16554            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16555        }
16556        // We always allow the memory level to go up (better).  We only allow it to go
16557        // down if we are in a state where that is allowed, *and* the total number of processes
16558        // has gone down since last time.
16559        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16560                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16561                + " last=" + mLastNumProcesses);
16562        if (memFactor > mLastMemoryLevel) {
16563            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16564                memFactor = mLastMemoryLevel;
16565                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16566            }
16567        }
16568        mLastMemoryLevel = memFactor;
16569        mLastNumProcesses = mLruProcesses.size();
16570        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16571        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16572        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16573            if (mLowRamStartTime == 0) {
16574                mLowRamStartTime = now;
16575            }
16576            int step = 0;
16577            int fgTrimLevel;
16578            switch (memFactor) {
16579                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16580                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16581                    break;
16582                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16583                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16584                    break;
16585                default:
16586                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16587                    break;
16588            }
16589            int factor = numTrimming/3;
16590            int minFactor = 2;
16591            if (mHomeProcess != null) minFactor++;
16592            if (mPreviousProcess != null) minFactor++;
16593            if (factor < minFactor) factor = minFactor;
16594            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16595            for (int i=N-1; i>=0; i--) {
16596                ProcessRecord app = mLruProcesses.get(i);
16597                if (allChanged || app.procStateChanged) {
16598                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16599                    app.procStateChanged = false;
16600                }
16601                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16602                        && !app.killedByAm) {
16603                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16604                        try {
16605                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16606                                    "Trimming memory of " + app.processName
16607                                    + " to " + curLevel);
16608                            app.thread.scheduleTrimMemory(curLevel);
16609                        } catch (RemoteException e) {
16610                        }
16611                        if (false) {
16612                            // For now we won't do this; our memory trimming seems
16613                            // to be good enough at this point that destroying
16614                            // activities causes more harm than good.
16615                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16616                                    && app != mHomeProcess && app != mPreviousProcess) {
16617                                // Need to do this on its own message because the stack may not
16618                                // be in a consistent state at this point.
16619                                // For these apps we will also finish their activities
16620                                // to help them free memory.
16621                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16622                            }
16623                        }
16624                    }
16625                    app.trimMemoryLevel = curLevel;
16626                    step++;
16627                    if (step >= factor) {
16628                        step = 0;
16629                        switch (curLevel) {
16630                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16631                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16632                                break;
16633                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16634                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16635                                break;
16636                        }
16637                    }
16638                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16639                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16640                            && app.thread != null) {
16641                        try {
16642                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16643                                    "Trimming memory of heavy-weight " + app.processName
16644                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16645                            app.thread.scheduleTrimMemory(
16646                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16647                        } catch (RemoteException e) {
16648                        }
16649                    }
16650                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16651                } else {
16652                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16653                            || app.systemNoUi) && app.pendingUiClean) {
16654                        // If this application is now in the background and it
16655                        // had done UI, then give it the special trim level to
16656                        // have it free UI resources.
16657                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16658                        if (app.trimMemoryLevel < level && app.thread != null) {
16659                            try {
16660                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16661                                        "Trimming memory of bg-ui " + app.processName
16662                                        + " to " + level);
16663                                app.thread.scheduleTrimMemory(level);
16664                            } catch (RemoteException e) {
16665                            }
16666                        }
16667                        app.pendingUiClean = false;
16668                    }
16669                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16670                        try {
16671                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16672                                    "Trimming memory of fg " + app.processName
16673                                    + " to " + fgTrimLevel);
16674                            app.thread.scheduleTrimMemory(fgTrimLevel);
16675                        } catch (RemoteException e) {
16676                        }
16677                    }
16678                    app.trimMemoryLevel = fgTrimLevel;
16679                }
16680            }
16681        } else {
16682            if (mLowRamStartTime != 0) {
16683                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16684                mLowRamStartTime = 0;
16685            }
16686            for (int i=N-1; i>=0; i--) {
16687                ProcessRecord app = mLruProcesses.get(i);
16688                if (allChanged || app.procStateChanged) {
16689                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16690                    app.procStateChanged = false;
16691                }
16692                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16693                        || app.systemNoUi) && app.pendingUiClean) {
16694                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16695                            && app.thread != null) {
16696                        try {
16697                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16698                                    "Trimming memory of ui hidden " + app.processName
16699                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16700                            app.thread.scheduleTrimMemory(
16701                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16702                        } catch (RemoteException e) {
16703                        }
16704                    }
16705                    app.pendingUiClean = false;
16706                }
16707                app.trimMemoryLevel = 0;
16708            }
16709        }
16710
16711        if (mAlwaysFinishActivities) {
16712            // Need to do this on its own message because the stack may not
16713            // be in a consistent state at this point.
16714            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16715        }
16716
16717        if (allChanged) {
16718            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16719        }
16720
16721        if (mProcessStats.shouldWriteNowLocked(now)) {
16722            mHandler.post(new Runnable() {
16723                @Override public void run() {
16724                    synchronized (ActivityManagerService.this) {
16725                        mProcessStats.writeStateAsyncLocked();
16726                    }
16727                }
16728            });
16729        }
16730
16731        if (DEBUG_OOM_ADJ) {
16732            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16733        }
16734    }
16735
16736    final void trimApplications() {
16737        synchronized (this) {
16738            int i;
16739
16740            // First remove any unused application processes whose package
16741            // has been removed.
16742            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16743                final ProcessRecord app = mRemovedProcesses.get(i);
16744                if (app.activities.size() == 0
16745                        && app.curReceiver == null && app.services.size() == 0) {
16746                    Slog.i(
16747                        TAG, "Exiting empty application process "
16748                        + app.processName + " ("
16749                        + (app.thread != null ? app.thread.asBinder() : null)
16750                        + ")\n");
16751                    if (app.pid > 0 && app.pid != MY_PID) {
16752                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16753                                app.processName, app.setAdj, "empty");
16754                        app.killedByAm = true;
16755                        Process.killProcessQuiet(app.pid);
16756                        Process.killProcessGroup(app.info.uid, app.pid);
16757                    } else {
16758                        try {
16759                            app.thread.scheduleExit();
16760                        } catch (Exception e) {
16761                            // Ignore exceptions.
16762                        }
16763                    }
16764                    cleanUpApplicationRecordLocked(app, false, true, -1);
16765                    mRemovedProcesses.remove(i);
16766
16767                    if (app.persistent) {
16768                        addAppLocked(app.info, false, null /* ABI override */);
16769                    }
16770                }
16771            }
16772
16773            // Now update the oom adj for all processes.
16774            updateOomAdjLocked();
16775        }
16776    }
16777
16778    /** This method sends the specified signal to each of the persistent apps */
16779    public void signalPersistentProcesses(int sig) throws RemoteException {
16780        if (sig != Process.SIGNAL_USR1) {
16781            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16782        }
16783
16784        synchronized (this) {
16785            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16786                    != PackageManager.PERMISSION_GRANTED) {
16787                throw new SecurityException("Requires permission "
16788                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16789            }
16790
16791            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16792                ProcessRecord r = mLruProcesses.get(i);
16793                if (r.thread != null && r.persistent) {
16794                    Process.sendSignal(r.pid, sig);
16795                }
16796            }
16797        }
16798    }
16799
16800    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16801        if (proc == null || proc == mProfileProc) {
16802            proc = mProfileProc;
16803            path = mProfileFile;
16804            profileType = mProfileType;
16805            clearProfilerLocked();
16806        }
16807        if (proc == null) {
16808            return;
16809        }
16810        try {
16811            proc.thread.profilerControl(false, path, null, profileType);
16812        } catch (RemoteException e) {
16813            throw new IllegalStateException("Process disappeared");
16814        }
16815    }
16816
16817    private void clearProfilerLocked() {
16818        if (mProfileFd != null) {
16819            try {
16820                mProfileFd.close();
16821            } catch (IOException e) {
16822            }
16823        }
16824        mProfileApp = null;
16825        mProfileProc = null;
16826        mProfileFile = null;
16827        mProfileType = 0;
16828        mAutoStopProfiler = false;
16829    }
16830
16831    public boolean profileControl(String process, int userId, boolean start,
16832            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16833
16834        try {
16835            synchronized (this) {
16836                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16837                // its own permission.
16838                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16839                        != PackageManager.PERMISSION_GRANTED) {
16840                    throw new SecurityException("Requires permission "
16841                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16842                }
16843
16844                if (start && fd == null) {
16845                    throw new IllegalArgumentException("null fd");
16846                }
16847
16848                ProcessRecord proc = null;
16849                if (process != null) {
16850                    proc = findProcessLocked(process, userId, "profileControl");
16851                }
16852
16853                if (start && (proc == null || proc.thread == null)) {
16854                    throw new IllegalArgumentException("Unknown process: " + process);
16855                }
16856
16857                if (start) {
16858                    stopProfilerLocked(null, null, 0);
16859                    setProfileApp(proc.info, proc.processName, path, fd, false);
16860                    mProfileProc = proc;
16861                    mProfileType = profileType;
16862                    try {
16863                        fd = fd.dup();
16864                    } catch (IOException e) {
16865                        fd = null;
16866                    }
16867                    proc.thread.profilerControl(start, path, fd, profileType);
16868                    fd = null;
16869                    mProfileFd = null;
16870                } else {
16871                    stopProfilerLocked(proc, path, profileType);
16872                    if (fd != null) {
16873                        try {
16874                            fd.close();
16875                        } catch (IOException e) {
16876                        }
16877                    }
16878                }
16879
16880                return true;
16881            }
16882        } catch (RemoteException e) {
16883            throw new IllegalStateException("Process disappeared");
16884        } finally {
16885            if (fd != null) {
16886                try {
16887                    fd.close();
16888                } catch (IOException e) {
16889                }
16890            }
16891        }
16892    }
16893
16894    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16895        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16896                userId, true, ALLOW_FULL_ONLY, callName, null);
16897        ProcessRecord proc = null;
16898        try {
16899            int pid = Integer.parseInt(process);
16900            synchronized (mPidsSelfLocked) {
16901                proc = mPidsSelfLocked.get(pid);
16902            }
16903        } catch (NumberFormatException e) {
16904        }
16905
16906        if (proc == null) {
16907            ArrayMap<String, SparseArray<ProcessRecord>> all
16908                    = mProcessNames.getMap();
16909            SparseArray<ProcessRecord> procs = all.get(process);
16910            if (procs != null && procs.size() > 0) {
16911                proc = procs.valueAt(0);
16912                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16913                    for (int i=1; i<procs.size(); i++) {
16914                        ProcessRecord thisProc = procs.valueAt(i);
16915                        if (thisProc.userId == userId) {
16916                            proc = thisProc;
16917                            break;
16918                        }
16919                    }
16920                }
16921            }
16922        }
16923
16924        return proc;
16925    }
16926
16927    public boolean dumpHeap(String process, int userId, boolean managed,
16928            String path, ParcelFileDescriptor fd) throws RemoteException {
16929
16930        try {
16931            synchronized (this) {
16932                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16933                // its own permission (same as profileControl).
16934                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16935                        != PackageManager.PERMISSION_GRANTED) {
16936                    throw new SecurityException("Requires permission "
16937                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16938                }
16939
16940                if (fd == null) {
16941                    throw new IllegalArgumentException("null fd");
16942                }
16943
16944                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16945                if (proc == null || proc.thread == null) {
16946                    throw new IllegalArgumentException("Unknown process: " + process);
16947                }
16948
16949                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16950                if (!isDebuggable) {
16951                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16952                        throw new SecurityException("Process not debuggable: " + proc);
16953                    }
16954                }
16955
16956                proc.thread.dumpHeap(managed, path, fd);
16957                fd = null;
16958                return true;
16959            }
16960        } catch (RemoteException e) {
16961            throw new IllegalStateException("Process disappeared");
16962        } finally {
16963            if (fd != null) {
16964                try {
16965                    fd.close();
16966                } catch (IOException e) {
16967                }
16968            }
16969        }
16970    }
16971
16972    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16973    public void monitor() {
16974        synchronized (this) { }
16975    }
16976
16977    void onCoreSettingsChange(Bundle settings) {
16978        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16979            ProcessRecord processRecord = mLruProcesses.get(i);
16980            try {
16981                if (processRecord.thread != null) {
16982                    processRecord.thread.setCoreSettings(settings);
16983                }
16984            } catch (RemoteException re) {
16985                /* ignore */
16986            }
16987        }
16988    }
16989
16990    // Multi-user methods
16991
16992    /**
16993     * Start user, if its not already running, but don't bring it to foreground.
16994     */
16995    @Override
16996    public boolean startUserInBackground(final int userId) {
16997        return startUser(userId, /* foreground */ false);
16998    }
16999
17000    /**
17001     * Refreshes the list of users related to the current user when either a
17002     * user switch happens or when a new related user is started in the
17003     * background.
17004     */
17005    private void updateCurrentProfileIdsLocked() {
17006        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17007                mCurrentUserId, false /* enabledOnly */);
17008        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17009        for (int i = 0; i < currentProfileIds.length; i++) {
17010            currentProfileIds[i] = profiles.get(i).id;
17011        }
17012        mCurrentProfileIds = currentProfileIds;
17013
17014        synchronized (mUserProfileGroupIdsSelfLocked) {
17015            mUserProfileGroupIdsSelfLocked.clear();
17016            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17017            for (int i = 0; i < users.size(); i++) {
17018                UserInfo user = users.get(i);
17019                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17020                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17021                }
17022            }
17023        }
17024    }
17025
17026    private Set getProfileIdsLocked(int userId) {
17027        Set userIds = new HashSet<Integer>();
17028        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17029                userId, false /* enabledOnly */);
17030        for (UserInfo user : profiles) {
17031            userIds.add(Integer.valueOf(user.id));
17032        }
17033        return userIds;
17034    }
17035
17036    @Override
17037    public boolean switchUser(final int userId) {
17038        return startUser(userId, /* foregound */ true);
17039    }
17040
17041    private boolean startUser(final int userId, boolean foreground) {
17042        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17043                != PackageManager.PERMISSION_GRANTED) {
17044            String msg = "Permission Denial: switchUser() from pid="
17045                    + Binder.getCallingPid()
17046                    + ", uid=" + Binder.getCallingUid()
17047                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17048            Slog.w(TAG, msg);
17049            throw new SecurityException(msg);
17050        }
17051
17052        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17053
17054        final long ident = Binder.clearCallingIdentity();
17055        try {
17056            synchronized (this) {
17057                final int oldUserId = mCurrentUserId;
17058                if (oldUserId == userId) {
17059                    return true;
17060                }
17061
17062                mStackSupervisor.setLockTaskModeLocked(null, false);
17063
17064                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17065                if (userInfo == null) {
17066                    Slog.w(TAG, "No user info for user #" + userId);
17067                    return false;
17068                }
17069
17070                if (foreground) {
17071                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17072                            R.anim.screen_user_enter);
17073                }
17074
17075                boolean needStart = false;
17076
17077                // If the user we are switching to is not currently started, then
17078                // we need to start it now.
17079                if (mStartedUsers.get(userId) == null) {
17080                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17081                    updateStartedUserArrayLocked();
17082                    needStart = true;
17083                }
17084
17085                final Integer userIdInt = Integer.valueOf(userId);
17086                mUserLru.remove(userIdInt);
17087                mUserLru.add(userIdInt);
17088
17089                if (foreground) {
17090                    mCurrentUserId = userId;
17091                    updateCurrentProfileIdsLocked();
17092                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17093                    // Once the internal notion of the active user has switched, we lock the device
17094                    // with the option to show the user switcher on the keyguard.
17095                    mWindowManager.lockNow(null);
17096                } else {
17097                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17098                    updateCurrentProfileIdsLocked();
17099                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17100                    mUserLru.remove(currentUserIdInt);
17101                    mUserLru.add(currentUserIdInt);
17102                }
17103
17104                final UserStartedState uss = mStartedUsers.get(userId);
17105
17106                // Make sure user is in the started state.  If it is currently
17107                // stopping, we need to knock that off.
17108                if (uss.mState == UserStartedState.STATE_STOPPING) {
17109                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17110                    // so we can just fairly silently bring the user back from
17111                    // the almost-dead.
17112                    uss.mState = UserStartedState.STATE_RUNNING;
17113                    updateStartedUserArrayLocked();
17114                    needStart = true;
17115                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17116                    // This means ACTION_SHUTDOWN has been sent, so we will
17117                    // need to treat this as a new boot of the user.
17118                    uss.mState = UserStartedState.STATE_BOOTING;
17119                    updateStartedUserArrayLocked();
17120                    needStart = true;
17121                }
17122
17123                if (uss.mState == UserStartedState.STATE_BOOTING) {
17124                    // Booting up a new user, need to tell system services about it.
17125                    // Note that this is on the same handler as scheduling of broadcasts,
17126                    // which is important because it needs to go first.
17127                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17128                }
17129
17130                if (foreground) {
17131                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17132                            oldUserId));
17133                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17134                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17135                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17136                            oldUserId, userId, uss));
17137                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17138                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17139                }
17140
17141                if (needStart) {
17142                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17143                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17144                            | Intent.FLAG_RECEIVER_FOREGROUND);
17145                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17146                    broadcastIntentLocked(null, null, intent,
17147                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17148                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17149                }
17150
17151                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17152                    if (userId != UserHandle.USER_OWNER) {
17153                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17154                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17155                        broadcastIntentLocked(null, null, intent, null,
17156                                new IIntentReceiver.Stub() {
17157                                    public void performReceive(Intent intent, int resultCode,
17158                                            String data, Bundle extras, boolean ordered,
17159                                            boolean sticky, int sendingUser) {
17160                                        userInitialized(uss, userId);
17161                                    }
17162                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17163                                true, false, MY_PID, Process.SYSTEM_UID,
17164                                userId);
17165                        uss.initializing = true;
17166                    } else {
17167                        getUserManagerLocked().makeInitialized(userInfo.id);
17168                    }
17169                }
17170
17171                if (foreground) {
17172                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17173                    if (homeInFront) {
17174                        startHomeActivityLocked(userId);
17175                    } else {
17176                        mStackSupervisor.resumeTopActivitiesLocked();
17177                    }
17178                    EventLogTags.writeAmSwitchUser(userId);
17179                    getUserManagerLocked().userForeground(userId);
17180                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17181                } else {
17182                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17183                }
17184
17185                if (needStart) {
17186                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17187                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17188                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17189                    broadcastIntentLocked(null, null, intent,
17190                            null, new IIntentReceiver.Stub() {
17191                                @Override
17192                                public void performReceive(Intent intent, int resultCode, String data,
17193                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17194                                        throws RemoteException {
17195                                }
17196                            }, 0, null, null,
17197                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17198                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17199                }
17200            }
17201        } finally {
17202            Binder.restoreCallingIdentity(ident);
17203        }
17204
17205        return true;
17206    }
17207
17208    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17209        long ident = Binder.clearCallingIdentity();
17210        try {
17211            Intent intent;
17212            if (oldUserId >= 0) {
17213                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17214                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17215                int count = profiles.size();
17216                for (int i = 0; i < count; i++) {
17217                    int profileUserId = profiles.get(i).id;
17218                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17219                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17220                            | Intent.FLAG_RECEIVER_FOREGROUND);
17221                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17222                    broadcastIntentLocked(null, null, intent,
17223                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17224                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17225                }
17226            }
17227            if (newUserId >= 0) {
17228                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17229                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17230                int count = profiles.size();
17231                for (int i = 0; i < count; i++) {
17232                    int profileUserId = profiles.get(i).id;
17233                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17234                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17235                            | Intent.FLAG_RECEIVER_FOREGROUND);
17236                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17237                    broadcastIntentLocked(null, null, intent,
17238                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17239                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17240                }
17241                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17242                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17243                        | Intent.FLAG_RECEIVER_FOREGROUND);
17244                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17245                broadcastIntentLocked(null, null, intent,
17246                        null, null, 0, null, null,
17247                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17248                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17249            }
17250        } finally {
17251            Binder.restoreCallingIdentity(ident);
17252        }
17253    }
17254
17255    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17256            final int newUserId) {
17257        final int N = mUserSwitchObservers.beginBroadcast();
17258        if (N > 0) {
17259            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17260                int mCount = 0;
17261                @Override
17262                public void sendResult(Bundle data) throws RemoteException {
17263                    synchronized (ActivityManagerService.this) {
17264                        if (mCurUserSwitchCallback == this) {
17265                            mCount++;
17266                            if (mCount == N) {
17267                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17268                            }
17269                        }
17270                    }
17271                }
17272            };
17273            synchronized (this) {
17274                uss.switching = true;
17275                mCurUserSwitchCallback = callback;
17276            }
17277            for (int i=0; i<N; i++) {
17278                try {
17279                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17280                            newUserId, callback);
17281                } catch (RemoteException e) {
17282                }
17283            }
17284        } else {
17285            synchronized (this) {
17286                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17287            }
17288        }
17289        mUserSwitchObservers.finishBroadcast();
17290    }
17291
17292    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17293        synchronized (this) {
17294            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17295            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17296        }
17297    }
17298
17299    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17300        mCurUserSwitchCallback = null;
17301        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17302        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17303                oldUserId, newUserId, uss));
17304    }
17305
17306    void userInitialized(UserStartedState uss, int newUserId) {
17307        completeSwitchAndInitalize(uss, newUserId, true, false);
17308    }
17309
17310    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17311        completeSwitchAndInitalize(uss, newUserId, false, true);
17312    }
17313
17314    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17315            boolean clearInitializing, boolean clearSwitching) {
17316        boolean unfrozen = false;
17317        synchronized (this) {
17318            if (clearInitializing) {
17319                uss.initializing = false;
17320                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17321            }
17322            if (clearSwitching) {
17323                uss.switching = false;
17324            }
17325            if (!uss.switching && !uss.initializing) {
17326                mWindowManager.stopFreezingScreen();
17327                unfrozen = true;
17328            }
17329        }
17330        if (unfrozen) {
17331            final int N = mUserSwitchObservers.beginBroadcast();
17332            for (int i=0; i<N; i++) {
17333                try {
17334                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17335                } catch (RemoteException e) {
17336                }
17337            }
17338            mUserSwitchObservers.finishBroadcast();
17339        }
17340    }
17341
17342    void scheduleStartProfilesLocked() {
17343        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17344            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17345                    DateUtils.SECOND_IN_MILLIS);
17346        }
17347    }
17348
17349    void startProfilesLocked() {
17350        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17351        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17352                mCurrentUserId, false /* enabledOnly */);
17353        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17354        for (UserInfo user : profiles) {
17355            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17356                    && user.id != mCurrentUserId) {
17357                toStart.add(user);
17358            }
17359        }
17360        final int n = toStart.size();
17361        int i = 0;
17362        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17363            startUserInBackground(toStart.get(i).id);
17364        }
17365        if (i < n) {
17366            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17367        }
17368    }
17369
17370    void finishUserBoot(UserStartedState uss) {
17371        synchronized (this) {
17372            if (uss.mState == UserStartedState.STATE_BOOTING
17373                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17374                uss.mState = UserStartedState.STATE_RUNNING;
17375                final int userId = uss.mHandle.getIdentifier();
17376                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17377                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17378                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17379                broadcastIntentLocked(null, null, intent,
17380                        null, null, 0, null, null,
17381                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17382                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17383            }
17384        }
17385    }
17386
17387    void finishUserSwitch(UserStartedState uss) {
17388        synchronized (this) {
17389            finishUserBoot(uss);
17390
17391            startProfilesLocked();
17392
17393            int num = mUserLru.size();
17394            int i = 0;
17395            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17396                Integer oldUserId = mUserLru.get(i);
17397                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17398                if (oldUss == null) {
17399                    // Shouldn't happen, but be sane if it does.
17400                    mUserLru.remove(i);
17401                    num--;
17402                    continue;
17403                }
17404                if (oldUss.mState == UserStartedState.STATE_STOPPING
17405                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17406                    // This user is already stopping, doesn't count.
17407                    num--;
17408                    i++;
17409                    continue;
17410                }
17411                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17412                    // Owner and current can't be stopped, but count as running.
17413                    i++;
17414                    continue;
17415                }
17416                // This is a user to be stopped.
17417                stopUserLocked(oldUserId, null);
17418                num--;
17419                i++;
17420            }
17421        }
17422    }
17423
17424    @Override
17425    public int stopUser(final int userId, final IStopUserCallback callback) {
17426        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17427                != PackageManager.PERMISSION_GRANTED) {
17428            String msg = "Permission Denial: switchUser() from pid="
17429                    + Binder.getCallingPid()
17430                    + ", uid=" + Binder.getCallingUid()
17431                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17432            Slog.w(TAG, msg);
17433            throw new SecurityException(msg);
17434        }
17435        if (userId <= 0) {
17436            throw new IllegalArgumentException("Can't stop primary user " + userId);
17437        }
17438        synchronized (this) {
17439            return stopUserLocked(userId, callback);
17440        }
17441    }
17442
17443    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17444        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17445        if (mCurrentUserId == userId) {
17446            return ActivityManager.USER_OP_IS_CURRENT;
17447        }
17448
17449        final UserStartedState uss = mStartedUsers.get(userId);
17450        if (uss == null) {
17451            // User is not started, nothing to do...  but we do need to
17452            // callback if requested.
17453            if (callback != null) {
17454                mHandler.post(new Runnable() {
17455                    @Override
17456                    public void run() {
17457                        try {
17458                            callback.userStopped(userId);
17459                        } catch (RemoteException e) {
17460                        }
17461                    }
17462                });
17463            }
17464            return ActivityManager.USER_OP_SUCCESS;
17465        }
17466
17467        if (callback != null) {
17468            uss.mStopCallbacks.add(callback);
17469        }
17470
17471        if (uss.mState != UserStartedState.STATE_STOPPING
17472                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17473            uss.mState = UserStartedState.STATE_STOPPING;
17474            updateStartedUserArrayLocked();
17475
17476            long ident = Binder.clearCallingIdentity();
17477            try {
17478                // We are going to broadcast ACTION_USER_STOPPING and then
17479                // once that is done send a final ACTION_SHUTDOWN and then
17480                // stop the user.
17481                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17482                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17483                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17484                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17485                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17486                // This is the result receiver for the final shutdown broadcast.
17487                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17488                    @Override
17489                    public void performReceive(Intent intent, int resultCode, String data,
17490                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17491                        finishUserStop(uss);
17492                    }
17493                };
17494                // This is the result receiver for the initial stopping broadcast.
17495                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17496                    @Override
17497                    public void performReceive(Intent intent, int resultCode, String data,
17498                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17499                        // On to the next.
17500                        synchronized (ActivityManagerService.this) {
17501                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17502                                // Whoops, we are being started back up.  Abort, abort!
17503                                return;
17504                            }
17505                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17506                        }
17507                        mBatteryStatsService.noteEvent(
17508                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17509                                Integer.toString(userId), userId);
17510                        mSystemServiceManager.stopUser(userId);
17511                        broadcastIntentLocked(null, null, shutdownIntent,
17512                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17513                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17514                    }
17515                };
17516                // Kick things off.
17517                broadcastIntentLocked(null, null, stoppingIntent,
17518                        null, stoppingReceiver, 0, null, null,
17519                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17520                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17521            } finally {
17522                Binder.restoreCallingIdentity(ident);
17523            }
17524        }
17525
17526        return ActivityManager.USER_OP_SUCCESS;
17527    }
17528
17529    void finishUserStop(UserStartedState uss) {
17530        final int userId = uss.mHandle.getIdentifier();
17531        boolean stopped;
17532        ArrayList<IStopUserCallback> callbacks;
17533        synchronized (this) {
17534            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17535            if (mStartedUsers.get(userId) != uss) {
17536                stopped = false;
17537            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17538                stopped = false;
17539            } else {
17540                stopped = true;
17541                // User can no longer run.
17542                mStartedUsers.remove(userId);
17543                mUserLru.remove(Integer.valueOf(userId));
17544                updateStartedUserArrayLocked();
17545
17546                // Clean up all state and processes associated with the user.
17547                // Kill all the processes for the user.
17548                forceStopUserLocked(userId, "finish user");
17549            }
17550        }
17551
17552        for (int i=0; i<callbacks.size(); i++) {
17553            try {
17554                if (stopped) callbacks.get(i).userStopped(userId);
17555                else callbacks.get(i).userStopAborted(userId);
17556            } catch (RemoteException e) {
17557            }
17558        }
17559
17560        if (stopped) {
17561            mSystemServiceManager.cleanupUser(userId);
17562            synchronized (this) {
17563                mStackSupervisor.removeUserLocked(userId);
17564            }
17565        }
17566    }
17567
17568    @Override
17569    public UserInfo getCurrentUser() {
17570        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17571                != PackageManager.PERMISSION_GRANTED) && (
17572                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17573                != PackageManager.PERMISSION_GRANTED)) {
17574            String msg = "Permission Denial: getCurrentUser() from pid="
17575                    + Binder.getCallingPid()
17576                    + ", uid=" + Binder.getCallingUid()
17577                    + " requires " + INTERACT_ACROSS_USERS;
17578            Slog.w(TAG, msg);
17579            throw new SecurityException(msg);
17580        }
17581        synchronized (this) {
17582            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17583        }
17584    }
17585
17586    int getCurrentUserIdLocked() {
17587        return mCurrentUserId;
17588    }
17589
17590    @Override
17591    public boolean isUserRunning(int userId, boolean orStopped) {
17592        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17593                != PackageManager.PERMISSION_GRANTED) {
17594            String msg = "Permission Denial: isUserRunning() from pid="
17595                    + Binder.getCallingPid()
17596                    + ", uid=" + Binder.getCallingUid()
17597                    + " requires " + INTERACT_ACROSS_USERS;
17598            Slog.w(TAG, msg);
17599            throw new SecurityException(msg);
17600        }
17601        synchronized (this) {
17602            return isUserRunningLocked(userId, orStopped);
17603        }
17604    }
17605
17606    boolean isUserRunningLocked(int userId, boolean orStopped) {
17607        UserStartedState state = mStartedUsers.get(userId);
17608        if (state == null) {
17609            return false;
17610        }
17611        if (orStopped) {
17612            return true;
17613        }
17614        return state.mState != UserStartedState.STATE_STOPPING
17615                && state.mState != UserStartedState.STATE_SHUTDOWN;
17616    }
17617
17618    @Override
17619    public int[] getRunningUserIds() {
17620        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17621                != PackageManager.PERMISSION_GRANTED) {
17622            String msg = "Permission Denial: isUserRunning() from pid="
17623                    + Binder.getCallingPid()
17624                    + ", uid=" + Binder.getCallingUid()
17625                    + " requires " + INTERACT_ACROSS_USERS;
17626            Slog.w(TAG, msg);
17627            throw new SecurityException(msg);
17628        }
17629        synchronized (this) {
17630            return mStartedUserArray;
17631        }
17632    }
17633
17634    private void updateStartedUserArrayLocked() {
17635        int num = 0;
17636        for (int i=0; i<mStartedUsers.size();  i++) {
17637            UserStartedState uss = mStartedUsers.valueAt(i);
17638            // This list does not include stopping users.
17639            if (uss.mState != UserStartedState.STATE_STOPPING
17640                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17641                num++;
17642            }
17643        }
17644        mStartedUserArray = new int[num];
17645        num = 0;
17646        for (int i=0; i<mStartedUsers.size();  i++) {
17647            UserStartedState uss = mStartedUsers.valueAt(i);
17648            if (uss.mState != UserStartedState.STATE_STOPPING
17649                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17650                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17651                num++;
17652            }
17653        }
17654    }
17655
17656    @Override
17657    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17658        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17659                != PackageManager.PERMISSION_GRANTED) {
17660            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17661                    + Binder.getCallingPid()
17662                    + ", uid=" + Binder.getCallingUid()
17663                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17664            Slog.w(TAG, msg);
17665            throw new SecurityException(msg);
17666        }
17667
17668        mUserSwitchObservers.register(observer);
17669    }
17670
17671    @Override
17672    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17673        mUserSwitchObservers.unregister(observer);
17674    }
17675
17676    private boolean userExists(int userId) {
17677        if (userId == 0) {
17678            return true;
17679        }
17680        UserManagerService ums = getUserManagerLocked();
17681        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17682    }
17683
17684    int[] getUsersLocked() {
17685        UserManagerService ums = getUserManagerLocked();
17686        return ums != null ? ums.getUserIds() : new int[] { 0 };
17687    }
17688
17689    UserManagerService getUserManagerLocked() {
17690        if (mUserManager == null) {
17691            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17692            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17693        }
17694        return mUserManager;
17695    }
17696
17697    private int applyUserId(int uid, int userId) {
17698        return UserHandle.getUid(userId, uid);
17699    }
17700
17701    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17702        if (info == null) return null;
17703        ApplicationInfo newInfo = new ApplicationInfo(info);
17704        newInfo.uid = applyUserId(info.uid, userId);
17705        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17706                + info.packageName;
17707        return newInfo;
17708    }
17709
17710    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17711        if (aInfo == null
17712                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17713            return aInfo;
17714        }
17715
17716        ActivityInfo info = new ActivityInfo(aInfo);
17717        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17718        return info;
17719    }
17720
17721    private final class LocalService extends ActivityManagerInternal {
17722        @Override
17723        public void goingToSleep() {
17724            ActivityManagerService.this.goingToSleep();
17725        }
17726
17727        @Override
17728        public void wakingUp() {
17729            ActivityManagerService.this.wakingUp();
17730        }
17731    }
17732
17733    /**
17734     * An implementation of IAppTask, that allows an app to manage its own tasks via
17735     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17736     * only the process that calls getAppTasks() can call the AppTask methods.
17737     */
17738    class AppTaskImpl extends IAppTask.Stub {
17739        private int mTaskId;
17740        private int mCallingUid;
17741
17742        public AppTaskImpl(int taskId, int callingUid) {
17743            mTaskId = taskId;
17744            mCallingUid = callingUid;
17745        }
17746
17747        @Override
17748        public void finishAndRemoveTask() {
17749            // Ensure that we are called from the same process that created this AppTask
17750            if (mCallingUid != Binder.getCallingUid()) {
17751                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17752                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17753                return;
17754            }
17755
17756            synchronized (ActivityManagerService.this) {
17757                long origId = Binder.clearCallingIdentity();
17758                try {
17759                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17760                    if (tr != null) {
17761                        // Only kill the process if we are not a new document
17762                        int flags = tr.getBaseIntent().getFlags();
17763                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17764                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17765                        removeTaskByIdLocked(mTaskId,
17766                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17767                    }
17768                } finally {
17769                    Binder.restoreCallingIdentity(origId);
17770                }
17771            }
17772        }
17773
17774        @Override
17775        public ActivityManager.RecentTaskInfo getTaskInfo() {
17776            // Ensure that we are called from the same process that created this AppTask
17777            if (mCallingUid != Binder.getCallingUid()) {
17778                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17779                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17780                return null;
17781            }
17782
17783            synchronized (ActivityManagerService.this) {
17784                long origId = Binder.clearCallingIdentity();
17785                try {
17786                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17787                    if (tr != null) {
17788                        return createRecentTaskInfoFromTaskRecord(tr);
17789                    }
17790                } finally {
17791                    Binder.restoreCallingIdentity(origId);
17792                }
17793                return null;
17794            }
17795        }
17796    }
17797}
17798