ActivityManagerService.java revision f329d050b8e72ba6daf67edc1b1b64b0035a6050
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_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.graphics.Rect;
40import android.os.BatteryStats;
41import android.os.PersistableBundle;
42import android.service.voice.IVoiceInteractionSession;
43import android.util.ArrayMap;
44
45import com.android.internal.R;
46import com.android.internal.annotations.GuardedBy;
47import com.android.internal.app.IAppOpsService;
48import com.android.internal.app.IVoiceInteractor;
49import com.android.internal.app.ProcessMap;
50import com.android.internal.app.ProcessStats;
51import com.android.internal.content.PackageMonitor;
52import com.android.internal.os.BackgroundThread;
53import com.android.internal.os.BatteryStatsImpl;
54import com.android.internal.os.ProcessCpuTracker;
55import com.android.internal.os.TransferPipe;
56import com.android.internal.os.Zygote;
57import com.android.internal.util.FastPrintWriter;
58import com.android.internal.util.FastXmlSerializer;
59import com.android.internal.util.MemInfoReader;
60import com.android.internal.util.Preconditions;
61import com.android.server.AppOpsService;
62import com.android.server.AttributeCache;
63import com.android.server.IntentResolver;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemService;
67import com.android.server.SystemServiceManager;
68import com.android.server.Watchdog;
69import com.android.server.am.ActivityStack.ActivityState;
70import com.android.server.firewall.IntentFirewall;
71import com.android.server.pm.UserManagerService;
72import com.android.server.wm.AppTransition;
73import com.android.server.wm.WindowManagerService;
74import com.google.android.collect.Lists;
75import com.google.android.collect.Maps;
76
77import libcore.io.IoUtils;
78
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
82
83import android.app.Activity;
84import android.app.ActivityManager;
85import android.app.ActivityManager.RunningTaskInfo;
86import android.app.ActivityManager.StackInfo;
87import android.app.ActivityManagerInternal;
88import android.app.ActivityManagerNative;
89import android.app.ActivityOptions;
90import android.app.ActivityThread;
91import android.app.AlertDialog;
92import android.app.AppGlobals;
93import android.app.ApplicationErrorReport;
94import android.app.Dialog;
95import android.app.IActivityController;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.IUiAutomationConnection;
103import android.app.IUserSwitchObserver;
104import android.app.Instrumentation;
105import android.app.Notification;
106import android.app.NotificationManager;
107import android.app.PendingIntent;
108import android.app.backup.IBackupManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.ParceledListSlice;
133import android.content.pm.UserInfo;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PathPermission;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.graphics.Bitmap;
142import android.net.Proxy;
143import android.net.ProxyInfo;
144import android.net.Uri;
145import android.os.Binder;
146import android.os.Build;
147import android.os.Bundle;
148import android.os.Debug;
149import android.os.DropBoxManager;
150import android.os.Environment;
151import android.os.FactoryTest;
152import android.os.FileObserver;
153import android.os.FileUtils;
154import android.os.Handler;
155import android.os.IBinder;
156import android.os.IPermissionController;
157import android.os.IRemoteCallback;
158import android.os.IUserManager;
159import android.os.Looper;
160import android.os.Message;
161import android.os.Parcel;
162import android.os.ParcelFileDescriptor;
163import android.os.Process;
164import android.os.RemoteCallbackList;
165import android.os.RemoteException;
166import android.os.SELinux;
167import android.os.ServiceManager;
168import android.os.StrictMode;
169import android.os.SystemClock;
170import android.os.SystemProperties;
171import android.os.UpdateLock;
172import android.os.UserHandle;
173import android.provider.Settings;
174import android.text.format.DateUtils;
175import android.text.format.Time;
176import android.util.AtomicFile;
177import android.util.EventLog;
178import android.util.Log;
179import android.util.Pair;
180import android.util.PrintWriterPrinter;
181import android.util.Slog;
182import android.util.SparseArray;
183import android.util.TimeUtils;
184import android.util.Xml;
185import android.view.Gravity;
186import android.view.LayoutInflater;
187import android.view.View;
188import android.view.WindowManager;
189
190import java.io.BufferedInputStream;
191import java.io.BufferedOutputStream;
192import java.io.DataInputStream;
193import java.io.DataOutputStream;
194import java.io.File;
195import java.io.FileDescriptor;
196import java.io.FileInputStream;
197import java.io.FileNotFoundException;
198import java.io.FileOutputStream;
199import java.io.IOException;
200import java.io.InputStreamReader;
201import java.io.PrintWriter;
202import java.io.StringWriter;
203import java.lang.ref.WeakReference;
204import java.util.ArrayList;
205import java.util.Arrays;
206import java.util.Collections;
207import java.util.Comparator;
208import java.util.HashMap;
209import java.util.HashSet;
210import java.util.Iterator;
211import java.util.List;
212import java.util.Locale;
213import java.util.Map;
214import java.util.Set;
215import java.util.concurrent.atomic.AtomicBoolean;
216import java.util.concurrent.atomic.AtomicLong;
217
218public final class ActivityManagerService extends ActivityManagerNative
219        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
220    private static final String USER_DATA_DIR = "/data/user/";
221    static final String TAG = "ActivityManager";
222    static final String TAG_MU = "ActivityManagerServiceMU";
223    static final boolean DEBUG = false;
224    static final boolean localLOGV = DEBUG;
225    static final boolean DEBUG_BACKUP = localLOGV || false;
226    static final boolean DEBUG_BROADCAST = localLOGV || false;
227    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
229    static final boolean DEBUG_CLEANUP = localLOGV || false;
230    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
231    static final boolean DEBUG_FOCUS = false;
232    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
233    static final boolean DEBUG_MU = localLOGV || false;
234    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
235    static final boolean DEBUG_LRU = localLOGV || false;
236    static final boolean DEBUG_PAUSE = localLOGV || false;
237    static final boolean DEBUG_POWER = localLOGV || false;
238    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
239    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
240    static final boolean DEBUG_PROCESSES = localLOGV || false;
241    static final boolean DEBUG_PROVIDER = localLOGV || false;
242    static final boolean DEBUG_RESULTS = localLOGV || false;
243    static final boolean DEBUG_SERVICE = localLOGV || false;
244    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
245    static final boolean DEBUG_STACK = localLOGV || false;
246    static final boolean DEBUG_SWITCH = localLOGV || false;
247    static final boolean DEBUG_TASKS = localLOGV || false;
248    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
249    static final boolean DEBUG_TRANSITION = localLOGV || false;
250    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
251    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
252    static final boolean DEBUG_VISBILITY = localLOGV || false;
253    static final boolean DEBUG_PSS = localLOGV || false;
254    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
255    static final boolean VALIDATE_TOKENS = false;
256    static final boolean SHOW_ACTIVITY_START_TIME = true;
257
258    // Control over CPU and battery monitoring.
259    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
260    static final boolean MONITOR_CPU_USAGE = true;
261    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
262    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
263    static final boolean MONITOR_THREAD_CPU_USAGE = false;
264
265    // The flags that are set for all calls we make to the package manager.
266    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
267
268    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
269
270    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
271
272    // Maximum number of recent tasks that we can remember.
273    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200;
274
275    // Amount of time after a call to stopAppSwitches() during which we will
276    // prevent further untrusted switches from happening.
277    static final long APP_SWITCH_DELAY_TIME = 5*1000;
278
279    // How long we wait for a launched process to attach to the activity manager
280    // before we decide it's never going to come up for real.
281    static final int PROC_START_TIMEOUT = 10*1000;
282
283    // How long we wait for a launched process to attach to the activity manager
284    // before we decide it's never going to come up for real, when the process was
285    // started with a wrapper for instrumentation (such as Valgrind) because it
286    // could take much longer than usual.
287    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
288
289    // How long to wait after going idle before forcing apps to GC.
290    static final int GC_TIMEOUT = 5*1000;
291
292    // The minimum amount of time between successive GC requests for a process.
293    static final int GC_MIN_INTERVAL = 60*1000;
294
295    // The minimum amount of time between successive PSS requests for a process.
296    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
297
298    // The minimum amount of time between successive PSS requests for a process
299    // when the request is due to the memory state being lowered.
300    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
301
302    // The rate at which we check for apps using excessive power -- 15 mins.
303    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
304
305    // The minimum sample duration we will allow before deciding we have
306    // enough data on wake locks to start killing things.
307    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
308
309    // The minimum sample duration we will allow before deciding we have
310    // enough data on CPU usage to start killing things.
311    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
312
313    // How long we allow a receiver to run before giving up on it.
314    static final int BROADCAST_FG_TIMEOUT = 10*1000;
315    static final int BROADCAST_BG_TIMEOUT = 60*1000;
316
317    // How long we wait until we timeout on key dispatching.
318    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
319
320    // How long we wait until we timeout on key dispatching during instrumentation.
321    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
322
323    // Amount of time we wait for observers to handle a user switch before
324    // giving up on them and unfreezing the screen.
325    static final int USER_SWITCH_TIMEOUT = 2*1000;
326
327    // Maximum number of users we allow to be running at a time.
328    static final int MAX_RUNNING_USERS = 3;
329
330    // How long to wait in getAssistContextExtras for the activity and foreground services
331    // to respond with the result.
332    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
333
334    // Maximum number of persisted Uri grants a package is allowed
335    static final int MAX_PERSISTED_URI_GRANTS = 128;
336
337    static final int MY_PID = Process.myPid();
338
339    static final String[] EMPTY_STRING_ARRAY = new String[0];
340
341    // How many bytes to write into the dropbox log before truncating
342    static final int DROPBOX_MAX_SIZE = 256 * 1024;
343
344    /** All system services */
345    SystemServiceManager mSystemServiceManager;
346
347    /** Run all ActivityStacks through this */
348    ActivityStackSupervisor mStackSupervisor;
349
350    public IntentFirewall mIntentFirewall;
351
352    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
353    // default actuion automatically.  Important for devices without direct input
354    // devices.
355    private boolean mShowDialogs = true;
356
357    /**
358     * Description of a request to start a new activity, which has been held
359     * due to app switches being disabled.
360     */
361    static class PendingActivityLaunch {
362        final ActivityRecord r;
363        final ActivityRecord sourceRecord;
364        final int startFlags;
365        final ActivityStack stack;
366
367        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
368                int _startFlags, ActivityStack _stack) {
369            r = _r;
370            sourceRecord = _sourceRecord;
371            startFlags = _startFlags;
372            stack = _stack;
373        }
374    }
375
376    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
377            = new ArrayList<PendingActivityLaunch>();
378
379    BroadcastQueue mFgBroadcastQueue;
380    BroadcastQueue mBgBroadcastQueue;
381    // Convenient for easy iteration over the queues. Foreground is first
382    // so that dispatch of foreground broadcasts gets precedence.
383    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
384
385    BroadcastQueue broadcastQueueForIntent(Intent intent) {
386        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
387        if (DEBUG_BACKGROUND_BROADCAST) {
388            Slog.i(TAG, "Broadcast intent " + intent + " on "
389                    + (isFg ? "foreground" : "background")
390                    + " queue");
391        }
392        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
393    }
394
395    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
396        for (BroadcastQueue queue : mBroadcastQueues) {
397            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
398            if (r != null) {
399                return r;
400            }
401        }
402        return null;
403    }
404
405    /**
406     * Activity we have told the window manager to have key focus.
407     */
408    ActivityRecord mFocusedActivity = null;
409
410    /**
411     * List of intents that were used to start the most recent tasks.
412     */
413    ArrayList<TaskRecord> mRecentTasks;
414
415    public class PendingAssistExtras extends Binder implements Runnable {
416        public final ActivityRecord activity;
417        public boolean haveResult = false;
418        public Bundle result = null;
419        public PendingAssistExtras(ActivityRecord _activity) {
420            activity = _activity;
421        }
422        @Override
423        public void run() {
424            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
425            synchronized (this) {
426                haveResult = true;
427                notifyAll();
428            }
429        }
430    }
431
432    final ArrayList<PendingAssistExtras> mPendingAssistExtras
433            = new ArrayList<PendingAssistExtras>();
434
435    /**
436     * Process management.
437     */
438    final ProcessList mProcessList = new ProcessList();
439
440    /**
441     * All of the applications we currently have running organized by name.
442     * The keys are strings of the application package name (as
443     * returned by the package manager), and the keys are ApplicationRecord
444     * objects.
445     */
446    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
447
448    /**
449     * Tracking long-term execution of processes to look for abuse and other
450     * bad app behavior.
451     */
452    final ProcessStatsService mProcessStats;
453
454    /**
455     * The currently running isolated processes.
456     */
457    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
458
459    /**
460     * Counter for assigning isolated process uids, to avoid frequently reusing the
461     * same ones.
462     */
463    int mNextIsolatedProcessUid = 0;
464
465    /**
466     * The currently running heavy-weight process, if any.
467     */
468    ProcessRecord mHeavyWeightProcess = null;
469
470    /**
471     * The last time that various processes have crashed.
472     */
473    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
474
475    /**
476     * Information about a process that is currently marked as bad.
477     */
478    static final class BadProcessInfo {
479        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
480            this.time = time;
481            this.shortMsg = shortMsg;
482            this.longMsg = longMsg;
483            this.stack = stack;
484        }
485
486        final long time;
487        final String shortMsg;
488        final String longMsg;
489        final String stack;
490    }
491
492    /**
493     * Set of applications that we consider to be bad, and will reject
494     * incoming broadcasts from (which the user has no control over).
495     * Processes are added to this set when they have crashed twice within
496     * a minimum amount of time; they are removed from it when they are
497     * later restarted (hopefully due to some user action).  The value is the
498     * time it was added to the list.
499     */
500    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
501
502    /**
503     * All of the processes we currently have running organized by pid.
504     * The keys are the pid running the application.
505     *
506     * <p>NOTE: This object is protected by its own lock, NOT the global
507     * activity manager lock!
508     */
509    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
510
511    /**
512     * All of the processes that have been forced to be foreground.  The key
513     * is the pid of the caller who requested it (we hold a death
514     * link on it).
515     */
516    abstract class ForegroundToken implements IBinder.DeathRecipient {
517        int pid;
518        IBinder token;
519    }
520    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
521
522    /**
523     * List of records for processes that someone had tried to start before the
524     * system was ready.  We don't start them at that point, but ensure they
525     * are started by the time booting is complete.
526     */
527    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
528
529    /**
530     * List of persistent applications that are in the process
531     * of being started.
532     */
533    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
534
535    /**
536     * Processes that are being forcibly torn down.
537     */
538    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
539
540    /**
541     * List of running applications, sorted by recent usage.
542     * The first entry in the list is the least recently used.
543     */
544    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
545
546    /**
547     * Where in mLruProcesses that the processes hosting activities start.
548     */
549    int mLruProcessActivityStart = 0;
550
551    /**
552     * Where in mLruProcesses that the processes hosting services start.
553     * This is after (lower index) than mLruProcessesActivityStart.
554     */
555    int mLruProcessServiceStart = 0;
556
557    /**
558     * List of processes that should gc as soon as things are idle.
559     */
560    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
561
562    /**
563     * Processes we want to collect PSS data from.
564     */
565    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
566
567    /**
568     * Last time we requested PSS data of all processes.
569     */
570    long mLastFullPssTime = SystemClock.uptimeMillis();
571
572    /**
573     * If set, the next time we collect PSS data we should do a full collection
574     * with data from native processes and the kernel.
575     */
576    boolean mFullPssPending = false;
577
578    /**
579     * This is the process holding what we currently consider to be
580     * the "home" activity.
581     */
582    ProcessRecord mHomeProcess;
583
584    /**
585     * This is the process holding the activity the user last visited that
586     * is in a different process from the one they are currently in.
587     */
588    ProcessRecord mPreviousProcess;
589
590    /**
591     * The time at which the previous process was last visible.
592     */
593    long mPreviousProcessVisibleTime;
594
595    /**
596     * Which uses have been started, so are allowed to run code.
597     */
598    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
599
600    /**
601     * LRU list of history of current users.  Most recently current is at the end.
602     */
603    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
604
605    /**
606     * Constant array of the users that are currently started.
607     */
608    int[] mStartedUserArray = new int[] { 0 };
609
610    /**
611     * Registered observers of the user switching mechanics.
612     */
613    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
614            = new RemoteCallbackList<IUserSwitchObserver>();
615
616    /**
617     * Currently active user switch.
618     */
619    Object mCurUserSwitchCallback;
620
621    /**
622     * Packages that the user has asked to have run in screen size
623     * compatibility mode instead of filling the screen.
624     */
625    final CompatModePackages mCompatModePackages;
626
627    /**
628     * Set of IntentSenderRecord objects that are currently active.
629     */
630    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
631            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
632
633    /**
634     * Fingerprints (hashCode()) of stack traces that we've
635     * already logged DropBox entries for.  Guarded by itself.  If
636     * something (rogue user app) forces this over
637     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
638     */
639    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
640    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
641
642    /**
643     * Strict Mode background batched logging state.
644     *
645     * The string buffer is guarded by itself, and its lock is also
646     * used to determine if another batched write is already
647     * in-flight.
648     */
649    private final StringBuilder mStrictModeBuffer = new StringBuilder();
650
651    /**
652     * Keeps track of all IIntentReceivers that have been registered for
653     * broadcasts.  Hash keys are the receiver IBinder, hash value is
654     * a ReceiverList.
655     */
656    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
657            new HashMap<IBinder, ReceiverList>();
658
659    /**
660     * Resolver for broadcast intents to registered receivers.
661     * Holds BroadcastFilter (subclass of IntentFilter).
662     */
663    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
664            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
665        @Override
666        protected boolean allowFilterResult(
667                BroadcastFilter filter, List<BroadcastFilter> dest) {
668            IBinder target = filter.receiverList.receiver.asBinder();
669            for (int i=dest.size()-1; i>=0; i--) {
670                if (dest.get(i).receiverList.receiver.asBinder() == target) {
671                    return false;
672                }
673            }
674            return true;
675        }
676
677        @Override
678        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
679            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
680                    || userId == filter.owningUserId) {
681                return super.newResult(filter, match, userId);
682            }
683            return null;
684        }
685
686        @Override
687        protected BroadcastFilter[] newArray(int size) {
688            return new BroadcastFilter[size];
689        }
690
691        @Override
692        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
693            return packageName.equals(filter.packageName);
694        }
695    };
696
697    /**
698     * State of all active sticky broadcasts per user.  Keys are the action of the
699     * sticky Intent, values are an ArrayList of all broadcasted intents with
700     * that action (which should usually be one).  The SparseArray is keyed
701     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
702     * for stickies that are sent to all users.
703     */
704    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
705            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
706
707    final ActiveServices mServices;
708
709    /**
710     * Backup/restore process management
711     */
712    String mBackupAppName = null;
713    BackupRecord mBackupTarget = null;
714
715    final ProviderMap mProviderMap;
716
717    /**
718     * List of content providers who have clients waiting for them.  The
719     * application is currently being launched and the provider will be
720     * removed from this list once it is published.
721     */
722    final ArrayList<ContentProviderRecord> mLaunchingProviders
723            = new ArrayList<ContentProviderRecord>();
724
725    /**
726     * File storing persisted {@link #mGrantedUriPermissions}.
727     */
728    private final AtomicFile mGrantFile;
729
730    /** XML constants used in {@link #mGrantFile} */
731    private static final String TAG_URI_GRANTS = "uri-grants";
732    private static final String TAG_URI_GRANT = "uri-grant";
733    private static final String ATTR_USER_HANDLE = "userHandle";
734    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
735    private static final String ATTR_TARGET_USER_ID = "targetUserId";
736    private static final String ATTR_SOURCE_PKG = "sourcePkg";
737    private static final String ATTR_TARGET_PKG = "targetPkg";
738    private static final String ATTR_URI = "uri";
739    private static final String ATTR_MODE_FLAGS = "modeFlags";
740    private static final String ATTR_CREATED_TIME = "createdTime";
741    private static final String ATTR_PREFIX = "prefix";
742
743    /**
744     * Global set of specific {@link Uri} permissions that have been granted.
745     * This optimized lookup structure maps from {@link UriPermission#targetUid}
746     * to {@link UriPermission#uri} to {@link UriPermission}.
747     */
748    @GuardedBy("this")
749    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
750            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
751
752    public static class GrantUri {
753        public final int sourceUserId;
754        public final Uri uri;
755        public boolean prefix;
756
757        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
758            this.sourceUserId = sourceUserId;
759            this.uri = uri;
760            this.prefix = prefix;
761        }
762
763        @Override
764        public int hashCode() {
765            return toString().hashCode();
766        }
767
768        @Override
769        public boolean equals(Object o) {
770            if (o instanceof GrantUri) {
771                GrantUri other = (GrantUri) o;
772                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
773                        && prefix == other.prefix;
774            }
775            return false;
776        }
777
778        @Override
779        public String toString() {
780            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
781            if (prefix) result += " [prefix]";
782            return result;
783        }
784
785        public String toSafeString() {
786            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
787            if (prefix) result += " [prefix]";
788            return result;
789        }
790
791        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
792            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
793                    ContentProvider.getUriWithoutUserId(uri), false);
794        }
795    }
796
797    CoreSettingsObserver mCoreSettingsObserver;
798
799    /**
800     * Thread-local storage used to carry caller permissions over through
801     * indirect content-provider access.
802     */
803    private class Identity {
804        public int pid;
805        public int uid;
806
807        Identity(int _pid, int _uid) {
808            pid = _pid;
809            uid = _uid;
810        }
811    }
812
813    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
814
815    /**
816     * All information we have collected about the runtime performance of
817     * any user id that can impact battery performance.
818     */
819    final BatteryStatsService mBatteryStatsService;
820
821    /**
822     * Information about component usage
823     */
824    final UsageStatsService mUsageStatsService;
825
826    /**
827     * Information about and control over application operations
828     */
829    final AppOpsService mAppOpsService;
830
831    /**
832     * Save recent tasks information across reboots.
833     */
834    final TaskPersister mTaskPersister;
835
836    /**
837     * Current configuration information.  HistoryRecord objects are given
838     * a reference to this object to indicate which configuration they are
839     * currently running in, so this object must be kept immutable.
840     */
841    Configuration mConfiguration = new Configuration();
842
843    /**
844     * Current sequencing integer of the configuration, for skipping old
845     * configurations.
846     */
847    int mConfigurationSeq = 0;
848
849    /**
850     * Hardware-reported OpenGLES version.
851     */
852    final int GL_ES_VERSION;
853
854    /**
855     * List of initialization arguments to pass to all processes when binding applications to them.
856     * For example, references to the commonly used services.
857     */
858    HashMap<String, IBinder> mAppBindArgs;
859
860    /**
861     * Temporary to avoid allocations.  Protected by main lock.
862     */
863    final StringBuilder mStringBuilder = new StringBuilder(256);
864
865    /**
866     * Used to control how we initialize the service.
867     */
868    ComponentName mTopComponent;
869    String mTopAction = Intent.ACTION_MAIN;
870    String mTopData;
871    boolean mProcessesReady = false;
872    boolean mSystemReady = false;
873    boolean mBooting = false;
874    boolean mWaitingUpdate = false;
875    boolean mDidUpdate = false;
876    boolean mOnBattery = false;
877    boolean mLaunchWarningShown = false;
878
879    Context mContext;
880
881    int mFactoryTest;
882
883    boolean mCheckedForSetup;
884
885    /**
886     * The time at which we will allow normal application switches again,
887     * after a call to {@link #stopAppSwitches()}.
888     */
889    long mAppSwitchesAllowedTime;
890
891    /**
892     * This is set to true after the first switch after mAppSwitchesAllowedTime
893     * is set; any switches after that will clear the time.
894     */
895    boolean mDidAppSwitch;
896
897    /**
898     * Last time (in realtime) at which we checked for power usage.
899     */
900    long mLastPowerCheckRealtime;
901
902    /**
903     * Last time (in uptime) at which we checked for power usage.
904     */
905    long mLastPowerCheckUptime;
906
907    /**
908     * Set while we are wanting to sleep, to prevent any
909     * activities from being started/resumed.
910     */
911    private boolean mSleeping = false;
912
913    /**
914     * Set while we are running a voice interaction.  This overrides
915     * sleeping while it is active.
916     */
917    private boolean mRunningVoice = false;
918
919    /**
920     * State of external calls telling us if the device is asleep.
921     */
922    private boolean mWentToSleep = false;
923
924    /**
925     * State of external call telling us if the lock screen is shown.
926     */
927    private boolean mLockScreenShown = false;
928
929    /**
930     * Set if we are shutting down the system, similar to sleeping.
931     */
932    boolean mShuttingDown = false;
933
934    /**
935     * Current sequence id for oom_adj computation traversal.
936     */
937    int mAdjSeq = 0;
938
939    /**
940     * Current sequence id for process LRU updating.
941     */
942    int mLruSeq = 0;
943
944    /**
945     * Keep track of the non-cached/empty process we last found, to help
946     * determine how to distribute cached/empty processes next time.
947     */
948    int mNumNonCachedProcs = 0;
949
950    /**
951     * Keep track of the number of cached hidden procs, to balance oom adj
952     * distribution between those and empty procs.
953     */
954    int mNumCachedHiddenProcs = 0;
955
956    /**
957     * Keep track of the number of service processes we last found, to
958     * determine on the next iteration which should be B services.
959     */
960    int mNumServiceProcs = 0;
961    int mNewNumAServiceProcs = 0;
962    int mNewNumServiceProcs = 0;
963
964    /**
965     * Allow the current computed overall memory level of the system to go down?
966     * This is set to false when we are killing processes for reasons other than
967     * memory management, so that the now smaller process list will not be taken as
968     * an indication that memory is tighter.
969     */
970    boolean mAllowLowerMemLevel = false;
971
972    /**
973     * The last computed memory level, for holding when we are in a state that
974     * processes are going away for other reasons.
975     */
976    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
977
978    /**
979     * The last total number of process we have, to determine if changes actually look
980     * like a shrinking number of process due to lower RAM.
981     */
982    int mLastNumProcesses;
983
984    /**
985     * The uptime of the last time we performed idle maintenance.
986     */
987    long mLastIdleTime = SystemClock.uptimeMillis();
988
989    /**
990     * Total time spent with RAM that has been added in the past since the last idle time.
991     */
992    long mLowRamTimeSinceLastIdle = 0;
993
994    /**
995     * If RAM is currently low, when that horrible situation started.
996     */
997    long mLowRamStartTime = 0;
998
999    /**
1000     * For reporting to battery stats the current top application.
1001     */
1002    private String mCurResumedPackage = null;
1003    private int mCurResumedUid = -1;
1004
1005    /**
1006     * For reporting to battery stats the apps currently running foreground
1007     * service.  The ProcessMap is package/uid tuples; each of these contain
1008     * an array of the currently foreground processes.
1009     */
1010    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1011            = new ProcessMap<ArrayList<ProcessRecord>>();
1012
1013    /**
1014     * This is set if we had to do a delayed dexopt of an app before launching
1015     * it, to increase the ANR timeouts in that case.
1016     */
1017    boolean mDidDexOpt;
1018
1019    /**
1020     * Set if the systemServer made a call to enterSafeMode.
1021     */
1022    boolean mSafeMode;
1023
1024    String mDebugApp = null;
1025    boolean mWaitForDebugger = false;
1026    boolean mDebugTransient = false;
1027    String mOrigDebugApp = null;
1028    boolean mOrigWaitForDebugger = false;
1029    boolean mAlwaysFinishActivities = false;
1030    IActivityController mController = null;
1031    String mProfileApp = null;
1032    ProcessRecord mProfileProc = null;
1033    String mProfileFile;
1034    ParcelFileDescriptor mProfileFd;
1035    int mProfileType = 0;
1036    boolean mAutoStopProfiler = false;
1037    String mOpenGlTraceApp = null;
1038
1039    static class ProcessChangeItem {
1040        static final int CHANGE_ACTIVITIES = 1<<0;
1041        static final int CHANGE_PROCESS_STATE = 1<<1;
1042        int changes;
1043        int uid;
1044        int pid;
1045        int processState;
1046        boolean foregroundActivities;
1047    }
1048
1049    final RemoteCallbackList<IProcessObserver> mProcessObservers
1050            = new RemoteCallbackList<IProcessObserver>();
1051    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1052
1053    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1056            = new ArrayList<ProcessChangeItem>();
1057
1058    /**
1059     * Runtime CPU use collection thread.  This object's lock is used to
1060     * protect all related state.
1061     */
1062    final Thread mProcessCpuThread;
1063
1064    /**
1065     * Used to collect process stats when showing not responding dialog.
1066     * Protected by mProcessCpuThread.
1067     */
1068    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1069            MONITOR_THREAD_CPU_USAGE);
1070    final AtomicLong mLastCpuTime = new AtomicLong(0);
1071    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1072
1073    long mLastWriteTime = 0;
1074
1075    /**
1076     * Used to retain an update lock when the foreground activity is in
1077     * immersive mode.
1078     */
1079    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1080
1081    /**
1082     * Set to true after the system has finished booting.
1083     */
1084    boolean mBooted = false;
1085
1086    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1087    int mProcessLimitOverride = -1;
1088
1089    WindowManagerService mWindowManager;
1090
1091    final ActivityThread mSystemThread;
1092
1093    int mCurrentUserId = 0;
1094    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1095    private UserManagerService mUserManager;
1096
1097    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1098        final ProcessRecord mApp;
1099        final int mPid;
1100        final IApplicationThread mAppThread;
1101
1102        AppDeathRecipient(ProcessRecord app, int pid,
1103                IApplicationThread thread) {
1104            if (localLOGV) Slog.v(
1105                TAG, "New death recipient " + this
1106                + " for thread " + thread.asBinder());
1107            mApp = app;
1108            mPid = pid;
1109            mAppThread = thread;
1110        }
1111
1112        @Override
1113        public void binderDied() {
1114            if (localLOGV) Slog.v(
1115                TAG, "Death received in " + this
1116                + " for thread " + mAppThread.asBinder());
1117            synchronized(ActivityManagerService.this) {
1118                appDiedLocked(mApp, mPid, mAppThread);
1119            }
1120        }
1121    }
1122
1123    static final int SHOW_ERROR_MSG = 1;
1124    static final int SHOW_NOT_RESPONDING_MSG = 2;
1125    static final int SHOW_FACTORY_ERROR_MSG = 3;
1126    static final int UPDATE_CONFIGURATION_MSG = 4;
1127    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1128    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1129    static final int SERVICE_TIMEOUT_MSG = 12;
1130    static final int UPDATE_TIME_ZONE = 13;
1131    static final int SHOW_UID_ERROR_MSG = 14;
1132    static final int IM_FEELING_LUCKY_MSG = 15;
1133    static final int PROC_START_TIMEOUT_MSG = 20;
1134    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1135    static final int KILL_APPLICATION_MSG = 22;
1136    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1137    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1138    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1139    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1140    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1141    static final int CLEAR_DNS_CACHE_MSG = 28;
1142    static final int UPDATE_HTTP_PROXY_MSG = 29;
1143    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1144    static final int DISPATCH_PROCESSES_CHANGED = 31;
1145    static final int DISPATCH_PROCESS_DIED = 32;
1146    static final int REPORT_MEM_USAGE_MSG = 33;
1147    static final int REPORT_USER_SWITCH_MSG = 34;
1148    static final int CONTINUE_USER_SWITCH_MSG = 35;
1149    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1150    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1151    static final int PERSIST_URI_GRANTS_MSG = 38;
1152    static final int REQUEST_ALL_PSS_MSG = 39;
1153    static final int START_PROFILES_MSG = 40;
1154    static final int UPDATE_TIME = 41;
1155    static final int SYSTEM_USER_START_MSG = 42;
1156    static final int SYSTEM_USER_CURRENT_MSG = 43;
1157
1158    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1159    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1160    static final int FIRST_COMPAT_MODE_MSG = 300;
1161    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1162
1163    AlertDialog mUidAlert;
1164    CompatModeDialog mCompatModeDialog;
1165    long mLastMemUsageReportTime = 0;
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    final ServiceThread mHandlerThread;
1174    final MainHandler mHandler;
1175
1176    final class MainHandler extends Handler {
1177        public MainHandler(Looper looper) {
1178            super(looper, null, true);
1179        }
1180
1181        @Override
1182        public void handleMessage(Message msg) {
1183            switch (msg.what) {
1184            case SHOW_ERROR_MSG: {
1185                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1186                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1187                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1188                synchronized (ActivityManagerService.this) {
1189                    ProcessRecord proc = (ProcessRecord)data.get("app");
1190                    AppErrorResult res = (AppErrorResult) data.get("result");
1191                    if (proc != null && proc.crashDialog != null) {
1192                        Slog.e(TAG, "App already has crash dialog: " + proc);
1193                        if (res != null) {
1194                            res.set(0);
1195                        }
1196                        return;
1197                    }
1198                    if (!showBackground && UserHandle.getAppId(proc.uid)
1199                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1200                            && proc.pid != MY_PID) {
1201                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1202                        if (res != null) {
1203                            res.set(0);
1204                        }
1205                        return;
1206                    }
1207                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1208                        Dialog d = new AppErrorDialog(mContext,
1209                                ActivityManagerService.this, res, proc);
1210                        d.show();
1211                        proc.crashDialog = d;
1212                    } else {
1213                        // The device is asleep, so just pretend that the user
1214                        // saw a crash dialog and hit "force quit".
1215                        if (res != null) {
1216                            res.set(0);
1217                        }
1218                    }
1219                }
1220
1221                ensureBootCompleted();
1222            } break;
1223            case SHOW_NOT_RESPONDING_MSG: {
1224                synchronized (ActivityManagerService.this) {
1225                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1226                    ProcessRecord proc = (ProcessRecord)data.get("app");
1227                    if (proc != null && proc.anrDialog != null) {
1228                        Slog.e(TAG, "App already has anr dialog: " + proc);
1229                        return;
1230                    }
1231
1232                    Intent intent = new Intent("android.intent.action.ANR");
1233                    if (!mProcessesReady) {
1234                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1235                                | Intent.FLAG_RECEIVER_FOREGROUND);
1236                    }
1237                    broadcastIntentLocked(null, null, intent,
1238                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1239                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1240
1241                    if (mShowDialogs) {
1242                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1243                                mContext, proc, (ActivityRecord)data.get("activity"),
1244                                msg.arg1 != 0);
1245                        d.show();
1246                        proc.anrDialog = d;
1247                    } else {
1248                        // Just kill the app if there is no dialog to be shown.
1249                        killAppAtUsersRequest(proc, null);
1250                    }
1251                }
1252
1253                ensureBootCompleted();
1254            } break;
1255            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1256                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1257                synchronized (ActivityManagerService.this) {
1258                    ProcessRecord proc = (ProcessRecord) data.get("app");
1259                    if (proc == null) {
1260                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1261                        break;
1262                    }
1263                    if (proc.crashDialog != null) {
1264                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1265                        return;
1266                    }
1267                    AppErrorResult res = (AppErrorResult) data.get("result");
1268                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1269                        Dialog d = new StrictModeViolationDialog(mContext,
1270                                ActivityManagerService.this, res, proc);
1271                        d.show();
1272                        proc.crashDialog = d;
1273                    } else {
1274                        // The device is asleep, so just pretend that the user
1275                        // saw a crash dialog and hit "force quit".
1276                        res.set(0);
1277                    }
1278                }
1279                ensureBootCompleted();
1280            } break;
1281            case SHOW_FACTORY_ERROR_MSG: {
1282                Dialog d = new FactoryErrorDialog(
1283                    mContext, msg.getData().getCharSequence("msg"));
1284                d.show();
1285                ensureBootCompleted();
1286            } break;
1287            case UPDATE_CONFIGURATION_MSG: {
1288                final ContentResolver resolver = mContext.getContentResolver();
1289                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1290            } break;
1291            case GC_BACKGROUND_PROCESSES_MSG: {
1292                synchronized (ActivityManagerService.this) {
1293                    performAppGcsIfAppropriateLocked();
1294                }
1295            } break;
1296            case WAIT_FOR_DEBUGGER_MSG: {
1297                synchronized (ActivityManagerService.this) {
1298                    ProcessRecord app = (ProcessRecord)msg.obj;
1299                    if (msg.arg1 != 0) {
1300                        if (!app.waitedForDebugger) {
1301                            Dialog d = new AppWaitingForDebuggerDialog(
1302                                    ActivityManagerService.this,
1303                                    mContext, app);
1304                            app.waitDialog = d;
1305                            app.waitedForDebugger = true;
1306                            d.show();
1307                        }
1308                    } else {
1309                        if (app.waitDialog != null) {
1310                            app.waitDialog.dismiss();
1311                            app.waitDialog = null;
1312                        }
1313                    }
1314                }
1315            } break;
1316            case SERVICE_TIMEOUT_MSG: {
1317                if (mDidDexOpt) {
1318                    mDidDexOpt = false;
1319                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1320                    nmsg.obj = msg.obj;
1321                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1322                    return;
1323                }
1324                mServices.serviceTimeout((ProcessRecord)msg.obj);
1325            } break;
1326            case UPDATE_TIME_ZONE: {
1327                synchronized (ActivityManagerService.this) {
1328                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1329                        ProcessRecord r = mLruProcesses.get(i);
1330                        if (r.thread != null) {
1331                            try {
1332                                r.thread.updateTimeZone();
1333                            } catch (RemoteException ex) {
1334                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1335                            }
1336                        }
1337                    }
1338                }
1339            } break;
1340            case CLEAR_DNS_CACHE_MSG: {
1341                synchronized (ActivityManagerService.this) {
1342                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1343                        ProcessRecord r = mLruProcesses.get(i);
1344                        if (r.thread != null) {
1345                            try {
1346                                r.thread.clearDnsCache();
1347                            } catch (RemoteException ex) {
1348                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1349                            }
1350                        }
1351                    }
1352                }
1353            } break;
1354            case UPDATE_HTTP_PROXY_MSG: {
1355                ProxyInfo proxy = (ProxyInfo)msg.obj;
1356                String host = "";
1357                String port = "";
1358                String exclList = "";
1359                Uri pacFileUrl = Uri.EMPTY;
1360                if (proxy != null) {
1361                    host = proxy.getHost();
1362                    port = Integer.toString(proxy.getPort());
1363                    exclList = proxy.getExclusionListAsString();
1364                    pacFileUrl = proxy.getPacFileUrl();
1365                }
1366                synchronized (ActivityManagerService.this) {
1367                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1368                        ProcessRecord r = mLruProcesses.get(i);
1369                        if (r.thread != null) {
1370                            try {
1371                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1372                            } catch (RemoteException ex) {
1373                                Slog.w(TAG, "Failed to update http proxy for: " +
1374                                        r.info.processName);
1375                            }
1376                        }
1377                    }
1378                }
1379            } break;
1380            case SHOW_UID_ERROR_MSG: {
1381                String title = "System UIDs Inconsistent";
1382                String text = "UIDs on the system are inconsistent, you need to wipe your"
1383                        + " data partition or your device will be unstable.";
1384                Log.e(TAG, title + ": " + text);
1385                if (mShowDialogs) {
1386                    // XXX This is a temporary dialog, no need to localize.
1387                    AlertDialog d = new BaseErrorDialog(mContext);
1388                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1389                    d.setCancelable(false);
1390                    d.setTitle(title);
1391                    d.setMessage(text);
1392                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1393                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1394                    mUidAlert = d;
1395                    d.show();
1396                }
1397            } break;
1398            case IM_FEELING_LUCKY_MSG: {
1399                if (mUidAlert != null) {
1400                    mUidAlert.dismiss();
1401                    mUidAlert = null;
1402                }
1403            } break;
1404            case PROC_START_TIMEOUT_MSG: {
1405                if (mDidDexOpt) {
1406                    mDidDexOpt = false;
1407                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1408                    nmsg.obj = msg.obj;
1409                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1410                    return;
1411                }
1412                ProcessRecord app = (ProcessRecord)msg.obj;
1413                synchronized (ActivityManagerService.this) {
1414                    processStartTimedOutLocked(app);
1415                }
1416            } break;
1417            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1418                synchronized (ActivityManagerService.this) {
1419                    doPendingActivityLaunchesLocked(true);
1420                }
1421            } break;
1422            case KILL_APPLICATION_MSG: {
1423                synchronized (ActivityManagerService.this) {
1424                    int appid = msg.arg1;
1425                    boolean restart = (msg.arg2 == 1);
1426                    Bundle bundle = (Bundle)msg.obj;
1427                    String pkg = bundle.getString("pkg");
1428                    String reason = bundle.getString("reason");
1429                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1430                            false, UserHandle.USER_ALL, reason);
1431                }
1432            } break;
1433            case FINALIZE_PENDING_INTENT_MSG: {
1434                ((PendingIntentRecord)msg.obj).completeFinalize();
1435            } break;
1436            case POST_HEAVY_NOTIFICATION_MSG: {
1437                INotificationManager inm = NotificationManager.getService();
1438                if (inm == null) {
1439                    return;
1440                }
1441
1442                ActivityRecord root = (ActivityRecord)msg.obj;
1443                ProcessRecord process = root.app;
1444                if (process == null) {
1445                    return;
1446                }
1447
1448                try {
1449                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1450                    String text = mContext.getString(R.string.heavy_weight_notification,
1451                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1452                    Notification notification = new Notification();
1453                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1454                    notification.when = 0;
1455                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1456                    notification.tickerText = text;
1457                    notification.defaults = 0; // please be quiet
1458                    notification.sound = null;
1459                    notification.vibrate = null;
1460                    notification.setLatestEventInfo(context, text,
1461                            mContext.getText(R.string.heavy_weight_notification_detail),
1462                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1463                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1464                                    new UserHandle(root.userId)));
1465
1466                    try {
1467                        int[] outId = new int[1];
1468                        inm.enqueueNotificationWithTag("android", "android", null,
1469                                R.string.heavy_weight_notification,
1470                                notification, outId, root.userId);
1471                    } catch (RuntimeException e) {
1472                        Slog.w(ActivityManagerService.TAG,
1473                                "Error showing notification for heavy-weight app", e);
1474                    } catch (RemoteException e) {
1475                    }
1476                } catch (NameNotFoundException e) {
1477                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1478                }
1479            } break;
1480            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1481                INotificationManager inm = NotificationManager.getService();
1482                if (inm == null) {
1483                    return;
1484                }
1485                try {
1486                    inm.cancelNotificationWithTag("android", null,
1487                            R.string.heavy_weight_notification,  msg.arg1);
1488                } catch (RuntimeException e) {
1489                    Slog.w(ActivityManagerService.TAG,
1490                            "Error canceling notification for service", e);
1491                } catch (RemoteException e) {
1492                }
1493            } break;
1494            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1495                synchronized (ActivityManagerService.this) {
1496                    checkExcessivePowerUsageLocked(true);
1497                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1498                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1499                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1500                }
1501            } break;
1502            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1503                synchronized (ActivityManagerService.this) {
1504                    ActivityRecord ar = (ActivityRecord)msg.obj;
1505                    if (mCompatModeDialog != null) {
1506                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1507                                ar.info.applicationInfo.packageName)) {
1508                            return;
1509                        }
1510                        mCompatModeDialog.dismiss();
1511                        mCompatModeDialog = null;
1512                    }
1513                    if (ar != null && false) {
1514                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1515                                ar.packageName)) {
1516                            int mode = mCompatModePackages.computeCompatModeLocked(
1517                                    ar.info.applicationInfo);
1518                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1519                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1520                                mCompatModeDialog = new CompatModeDialog(
1521                                        ActivityManagerService.this, mContext,
1522                                        ar.info.applicationInfo);
1523                                mCompatModeDialog.show();
1524                            }
1525                        }
1526                    }
1527                }
1528                break;
1529            }
1530            case DISPATCH_PROCESSES_CHANGED: {
1531                dispatchProcessesChanged();
1532                break;
1533            }
1534            case DISPATCH_PROCESS_DIED: {
1535                final int pid = msg.arg1;
1536                final int uid = msg.arg2;
1537                dispatchProcessDied(pid, uid);
1538                break;
1539            }
1540            case REPORT_MEM_USAGE_MSG: {
1541                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1542                Thread thread = new Thread() {
1543                    @Override public void run() {
1544                        final SparseArray<ProcessMemInfo> infoMap
1545                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1546                        for (int i=0, N=memInfos.size(); i<N; i++) {
1547                            ProcessMemInfo mi = memInfos.get(i);
1548                            infoMap.put(mi.pid, mi);
1549                        }
1550                        updateCpuStatsNow();
1551                        synchronized (mProcessCpuThread) {
1552                            final int N = mProcessCpuTracker.countStats();
1553                            for (int i=0; i<N; i++) {
1554                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1555                                if (st.vsize > 0) {
1556                                    long pss = Debug.getPss(st.pid, null);
1557                                    if (pss > 0) {
1558                                        if (infoMap.indexOfKey(st.pid) < 0) {
1559                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1560                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1561                                            mi.pss = pss;
1562                                            memInfos.add(mi);
1563                                        }
1564                                    }
1565                                }
1566                            }
1567                        }
1568
1569                        long totalPss = 0;
1570                        for (int i=0, N=memInfos.size(); i<N; i++) {
1571                            ProcessMemInfo mi = memInfos.get(i);
1572                            if (mi.pss == 0) {
1573                                mi.pss = Debug.getPss(mi.pid, null);
1574                            }
1575                            totalPss += mi.pss;
1576                        }
1577                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1578                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1579                                if (lhs.oomAdj != rhs.oomAdj) {
1580                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1581                                }
1582                                if (lhs.pss != rhs.pss) {
1583                                    return lhs.pss < rhs.pss ? 1 : -1;
1584                                }
1585                                return 0;
1586                            }
1587                        });
1588
1589                        StringBuilder tag = new StringBuilder(128);
1590                        StringBuilder stack = new StringBuilder(128);
1591                        tag.append("Low on memory -- ");
1592                        appendMemBucket(tag, totalPss, "total", false);
1593                        appendMemBucket(stack, totalPss, "total", true);
1594
1595                        StringBuilder logBuilder = new StringBuilder(1024);
1596                        logBuilder.append("Low on memory:\n");
1597
1598                        boolean firstLine = true;
1599                        int lastOomAdj = Integer.MIN_VALUE;
1600                        for (int i=0, N=memInfos.size(); i<N; i++) {
1601                            ProcessMemInfo mi = memInfos.get(i);
1602
1603                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1604                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1605                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1606                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1607                                if (lastOomAdj != mi.oomAdj) {
1608                                    lastOomAdj = mi.oomAdj;
1609                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1610                                        tag.append(" / ");
1611                                    }
1612                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1613                                        if (firstLine) {
1614                                            stack.append(":");
1615                                            firstLine = false;
1616                                        }
1617                                        stack.append("\n\t at ");
1618                                    } else {
1619                                        stack.append("$");
1620                                    }
1621                                } else {
1622                                    tag.append(" ");
1623                                    stack.append("$");
1624                                }
1625                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1626                                    appendMemBucket(tag, mi.pss, mi.name, false);
1627                                }
1628                                appendMemBucket(stack, mi.pss, mi.name, true);
1629                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1630                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1631                                    stack.append("(");
1632                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1633                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1634                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1635                                            stack.append(":");
1636                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1637                                        }
1638                                    }
1639                                    stack.append(")");
1640                                }
1641                            }
1642
1643                            logBuilder.append("  ");
1644                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1645                            logBuilder.append(' ');
1646                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1647                            logBuilder.append(' ');
1648                            ProcessList.appendRamKb(logBuilder, mi.pss);
1649                            logBuilder.append(" kB: ");
1650                            logBuilder.append(mi.name);
1651                            logBuilder.append(" (");
1652                            logBuilder.append(mi.pid);
1653                            logBuilder.append(") ");
1654                            logBuilder.append(mi.adjType);
1655                            logBuilder.append('\n');
1656                            if (mi.adjReason != null) {
1657                                logBuilder.append("                      ");
1658                                logBuilder.append(mi.adjReason);
1659                                logBuilder.append('\n');
1660                            }
1661                        }
1662
1663                        logBuilder.append("           ");
1664                        ProcessList.appendRamKb(logBuilder, totalPss);
1665                        logBuilder.append(" kB: TOTAL\n");
1666
1667                        long[] infos = new long[Debug.MEMINFO_COUNT];
1668                        Debug.getMemInfo(infos);
1669                        logBuilder.append("  MemInfo: ");
1670                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1671                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1672                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1673                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1674                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1675                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1676                            logBuilder.append("  ZRAM: ");
1677                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1678                            logBuilder.append(" kB RAM, ");
1679                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1680                            logBuilder.append(" kB swap total, ");
1681                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1682                            logBuilder.append(" kB swap free\n");
1683                        }
1684                        Slog.i(TAG, logBuilder.toString());
1685
1686                        StringBuilder dropBuilder = new StringBuilder(1024);
1687                        /*
1688                        StringWriter oomSw = new StringWriter();
1689                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1690                        StringWriter catSw = new StringWriter();
1691                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1692                        String[] emptyArgs = new String[] { };
1693                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1694                        oomPw.flush();
1695                        String oomString = oomSw.toString();
1696                        */
1697                        dropBuilder.append(stack);
1698                        dropBuilder.append('\n');
1699                        dropBuilder.append('\n');
1700                        dropBuilder.append(logBuilder);
1701                        dropBuilder.append('\n');
1702                        /*
1703                        dropBuilder.append(oomString);
1704                        dropBuilder.append('\n');
1705                        */
1706                        StringWriter catSw = new StringWriter();
1707                        synchronized (ActivityManagerService.this) {
1708                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1709                            String[] emptyArgs = new String[] { };
1710                            catPw.println();
1711                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1712                            catPw.println();
1713                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1714                                    false, false, null);
1715                            catPw.println();
1716                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1717                            catPw.flush();
1718                        }
1719                        dropBuilder.append(catSw.toString());
1720                        addErrorToDropBox("lowmem", null, "system_server", null,
1721                                null, tag.toString(), dropBuilder.toString(), null, null);
1722                        //Slog.i(TAG, "Sent to dropbox:");
1723                        //Slog.i(TAG, dropBuilder.toString());
1724                        synchronized (ActivityManagerService.this) {
1725                            long now = SystemClock.uptimeMillis();
1726                            if (mLastMemUsageReportTime < now) {
1727                                mLastMemUsageReportTime = now;
1728                            }
1729                        }
1730                    }
1731                };
1732                thread.start();
1733                break;
1734            }
1735            case REPORT_USER_SWITCH_MSG: {
1736                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1737                break;
1738            }
1739            case CONTINUE_USER_SWITCH_MSG: {
1740                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1741                break;
1742            }
1743            case USER_SWITCH_TIMEOUT_MSG: {
1744                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1745                break;
1746            }
1747            case IMMERSIVE_MODE_LOCK_MSG: {
1748                final boolean nextState = (msg.arg1 != 0);
1749                if (mUpdateLock.isHeld() != nextState) {
1750                    if (DEBUG_IMMERSIVE) {
1751                        final ActivityRecord r = (ActivityRecord) msg.obj;
1752                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1753                    }
1754                    if (nextState) {
1755                        mUpdateLock.acquire();
1756                    } else {
1757                        mUpdateLock.release();
1758                    }
1759                }
1760                break;
1761            }
1762            case PERSIST_URI_GRANTS_MSG: {
1763                writeGrantedUriPermissions();
1764                break;
1765            }
1766            case REQUEST_ALL_PSS_MSG: {
1767                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1768                break;
1769            }
1770            case START_PROFILES_MSG: {
1771                synchronized (ActivityManagerService.this) {
1772                    startProfilesLocked();
1773                }
1774                break;
1775            }
1776            case UPDATE_TIME: {
1777                synchronized (ActivityManagerService.this) {
1778                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1779                        ProcessRecord r = mLruProcesses.get(i);
1780                        if (r.thread != null) {
1781                            try {
1782                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1783                            } catch (RemoteException ex) {
1784                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1785                            }
1786                        }
1787                    }
1788                }
1789                break;
1790            }
1791            case SYSTEM_USER_START_MSG: {
1792                mSystemServiceManager.startUser(msg.arg1);
1793                break;
1794            }
1795            case SYSTEM_USER_CURRENT_MSG: {
1796                mSystemServiceManager.switchUser(msg.arg1);
1797                break;
1798            }
1799            }
1800        }
1801    };
1802
1803    static final int COLLECT_PSS_BG_MSG = 1;
1804
1805    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1806        @Override
1807        public void handleMessage(Message msg) {
1808            switch (msg.what) {
1809            case COLLECT_PSS_BG_MSG: {
1810                long start = SystemClock.uptimeMillis();
1811                MemInfoReader memInfo = null;
1812                synchronized (ActivityManagerService.this) {
1813                    if (mFullPssPending) {
1814                        mFullPssPending = false;
1815                        memInfo = new MemInfoReader();
1816                    }
1817                }
1818                if (memInfo != null) {
1819                    updateCpuStatsNow();
1820                    long nativeTotalPss = 0;
1821                    synchronized (mProcessCpuThread) {
1822                        final int N = mProcessCpuTracker.countStats();
1823                        for (int j=0; j<N; j++) {
1824                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1825                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID
1826                                    || st.uid == Process.SYSTEM_UID) {
1827                                // This is definitely an application process; skip it.
1828                                continue;
1829                            }
1830                            synchronized (mPidsSelfLocked) {
1831                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1832                                    // This is one of our own processes; skip it.
1833                                    continue;
1834                                }
1835                            }
1836                            nativeTotalPss += Debug.getPss(st.pid, null);
1837                        }
1838                    }
1839                    memInfo.readMemInfo();
1840                    synchronized (this) {
1841                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1842                                + (SystemClock.uptimeMillis()-start) + "ms");
1843                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1844                                memInfo.getFreeSizeKb(),
1845                                memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(),
1846                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1847                                        +memInfo.getSlabSizeKb(),
1848                                nativeTotalPss);
1849                    }
1850                }
1851
1852                int i=0, num=0;
1853                long[] tmp = new long[1];
1854                do {
1855                    ProcessRecord proc;
1856                    int procState;
1857                    int pid;
1858                    synchronized (ActivityManagerService.this) {
1859                        if (i >= mPendingPssProcesses.size()) {
1860                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1861                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1862                            mPendingPssProcesses.clear();
1863                            return;
1864                        }
1865                        proc = mPendingPssProcesses.get(i);
1866                        procState = proc.pssProcState;
1867                        if (proc.thread != null && procState == proc.setProcState) {
1868                            pid = proc.pid;
1869                        } else {
1870                            proc = null;
1871                            pid = 0;
1872                        }
1873                        i++;
1874                    }
1875                    if (proc != null) {
1876                        long pss = Debug.getPss(pid, tmp);
1877                        synchronized (ActivityManagerService.this) {
1878                            if (proc.thread != null && proc.setProcState == procState
1879                                    && proc.pid == pid) {
1880                                num++;
1881                                proc.lastPssTime = SystemClock.uptimeMillis();
1882                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1883                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1884                                        + ": " + pss + " lastPss=" + proc.lastPss
1885                                        + " state=" + ProcessList.makeProcStateString(procState));
1886                                if (proc.initialIdlePss == 0) {
1887                                    proc.initialIdlePss = pss;
1888                                }
1889                                proc.lastPss = pss;
1890                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1891                                    proc.lastCachedPss = pss;
1892                                }
1893                            }
1894                        }
1895                    }
1896                } while (true);
1897            }
1898            }
1899        }
1900    };
1901
1902    /**
1903     * Monitor for package changes and update our internal state.
1904     */
1905    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1906        @Override
1907        public void onPackageRemoved(String packageName, int uid) {
1908            // Remove all tasks with activities in the specified package from the list of recent tasks
1909            synchronized (ActivityManagerService.this) {
1910                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1911                    TaskRecord tr = mRecentTasks.get(i);
1912                    ComponentName cn = tr.intent.getComponent();
1913                    if (cn != null && cn.getPackageName().equals(packageName)) {
1914                        // If the package name matches, remove the task and kill the process
1915                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1916                    }
1917                }
1918            }
1919        }
1920
1921        @Override
1922        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1923            onPackageModified(packageName);
1924            return true;
1925        }
1926
1927        @Override
1928        public void onPackageModified(String packageName) {
1929            final PackageManager pm = mContext.getPackageManager();
1930            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1931                    new ArrayList<Pair<Intent, Integer>>();
1932            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1933            // Copy the list of recent tasks so that we don't hold onto the lock on
1934            // ActivityManagerService for long periods while checking if components exist.
1935            synchronized (ActivityManagerService.this) {
1936                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1937                    TaskRecord tr = mRecentTasks.get(i);
1938                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1939                }
1940            }
1941            // Check the recent tasks and filter out all tasks with components that no longer exist.
1942            Intent tmpI = new Intent();
1943            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1944                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1945                ComponentName cn = p.first.getComponent();
1946                if (cn != null && cn.getPackageName().equals(packageName)) {
1947                    try {
1948                        // Add the task to the list to remove if the component no longer exists
1949                        tmpI.setComponent(cn);
1950                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1951                            tasksToRemove.add(p.second);
1952                        }
1953                    } catch (Exception e) {}
1954                }
1955            }
1956            // Prune all the tasks with removed components from the list of recent tasks
1957            synchronized (ActivityManagerService.this) {
1958                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1959                    // Remove the task but don't kill the process (since other components in that
1960                    // package may still be running and in the background)
1961                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1962                }
1963            }
1964        }
1965
1966        @Override
1967        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1968            // Force stop the specified packages
1969            if (packages != null) {
1970                for (String pkg : packages) {
1971                    synchronized (ActivityManagerService.this) {
1972                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1973                                "finished booting")) {
1974                            return true;
1975                        }
1976                    }
1977                }
1978            }
1979            return false;
1980        }
1981    };
1982
1983    public void setSystemProcess() {
1984        try {
1985            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1986            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1987            ServiceManager.addService("meminfo", new MemBinder(this));
1988            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1989            ServiceManager.addService("dbinfo", new DbBinder(this));
1990            if (MONITOR_CPU_USAGE) {
1991                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1992            }
1993            ServiceManager.addService("permission", new PermissionController(this));
1994
1995            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1996                    "android", STOCK_PM_FLAGS);
1997            mSystemThread.installSystemApplicationInfo(info);
1998
1999            synchronized (this) {
2000                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2001                app.persistent = true;
2002                app.pid = MY_PID;
2003                app.maxAdj = ProcessList.SYSTEM_ADJ;
2004                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2005                mProcessNames.put(app.processName, app.uid, app);
2006                synchronized (mPidsSelfLocked) {
2007                    mPidsSelfLocked.put(app.pid, app);
2008                }
2009                updateLruProcessLocked(app, false, null);
2010                updateOomAdjLocked();
2011            }
2012        } catch (PackageManager.NameNotFoundException e) {
2013            throw new RuntimeException(
2014                    "Unable to find android system package", e);
2015        }
2016    }
2017
2018    public void setWindowManager(WindowManagerService wm) {
2019        mWindowManager = wm;
2020        mStackSupervisor.setWindowManager(wm);
2021    }
2022
2023    public void startObservingNativeCrashes() {
2024        final NativeCrashListener ncl = new NativeCrashListener(this);
2025        ncl.start();
2026    }
2027
2028    public IAppOpsService getAppOpsService() {
2029        return mAppOpsService;
2030    }
2031
2032    static class MemBinder extends Binder {
2033        ActivityManagerService mActivityManagerService;
2034        MemBinder(ActivityManagerService activityManagerService) {
2035            mActivityManagerService = activityManagerService;
2036        }
2037
2038        @Override
2039        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2040            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2041                    != PackageManager.PERMISSION_GRANTED) {
2042                pw.println("Permission Denial: can't dump meminfo from from pid="
2043                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2044                        + " without permission " + android.Manifest.permission.DUMP);
2045                return;
2046            }
2047
2048            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2049        }
2050    }
2051
2052    static class GraphicsBinder extends Binder {
2053        ActivityManagerService mActivityManagerService;
2054        GraphicsBinder(ActivityManagerService activityManagerService) {
2055            mActivityManagerService = activityManagerService;
2056        }
2057
2058        @Override
2059        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2060            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2061                    != PackageManager.PERMISSION_GRANTED) {
2062                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2063                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2064                        + " without permission " + android.Manifest.permission.DUMP);
2065                return;
2066            }
2067
2068            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2069        }
2070    }
2071
2072    static class DbBinder extends Binder {
2073        ActivityManagerService mActivityManagerService;
2074        DbBinder(ActivityManagerService activityManagerService) {
2075            mActivityManagerService = activityManagerService;
2076        }
2077
2078        @Override
2079        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2080            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2081                    != PackageManager.PERMISSION_GRANTED) {
2082                pw.println("Permission Denial: can't dump dbinfo from from pid="
2083                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2084                        + " without permission " + android.Manifest.permission.DUMP);
2085                return;
2086            }
2087
2088            mActivityManagerService.dumpDbInfo(fd, pw, args);
2089        }
2090    }
2091
2092    static class CpuBinder extends Binder {
2093        ActivityManagerService mActivityManagerService;
2094        CpuBinder(ActivityManagerService activityManagerService) {
2095            mActivityManagerService = activityManagerService;
2096        }
2097
2098        @Override
2099        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2100            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2101                    != PackageManager.PERMISSION_GRANTED) {
2102                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2103                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2104                        + " without permission " + android.Manifest.permission.DUMP);
2105                return;
2106            }
2107
2108            synchronized (mActivityManagerService.mProcessCpuThread) {
2109                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2110                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2111                        SystemClock.uptimeMillis()));
2112            }
2113        }
2114    }
2115
2116    public static final class Lifecycle extends SystemService {
2117        private final ActivityManagerService mService;
2118
2119        public Lifecycle(Context context) {
2120            super(context);
2121            mService = new ActivityManagerService(context);
2122        }
2123
2124        @Override
2125        public void onStart() {
2126            mService.start();
2127        }
2128
2129        public ActivityManagerService getService() {
2130            return mService;
2131        }
2132    }
2133
2134    // Note: This method is invoked on the main thread but may need to attach various
2135    // handlers to other threads.  So take care to be explicit about the looper.
2136    public ActivityManagerService(Context systemContext) {
2137        mContext = systemContext;
2138        mFactoryTest = FactoryTest.getMode();
2139        mSystemThread = ActivityThread.currentActivityThread();
2140
2141        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2142
2143        mHandlerThread = new ServiceThread(TAG,
2144                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2145        mHandlerThread.start();
2146        mHandler = new MainHandler(mHandlerThread.getLooper());
2147
2148        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2149                "foreground", BROADCAST_FG_TIMEOUT, false);
2150        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2151                "background", BROADCAST_BG_TIMEOUT, true);
2152        mBroadcastQueues[0] = mFgBroadcastQueue;
2153        mBroadcastQueues[1] = mBgBroadcastQueue;
2154
2155        mServices = new ActiveServices(this);
2156        mProviderMap = new ProviderMap(this);
2157
2158        // TODO: Move creation of battery stats service outside of activity manager service.
2159        File dataDir = Environment.getDataDirectory();
2160        File systemDir = new File(dataDir, "system");
2161        systemDir.mkdirs();
2162        mBatteryStatsService = new BatteryStatsService(new File(
2163                systemDir, "batterystats.bin").toString(), mHandler);
2164        mBatteryStatsService.getActiveStatistics().readLocked();
2165        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2166        mOnBattery = DEBUG_POWER ? true
2167                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2168        mBatteryStatsService.getActiveStatistics().setCallback(this);
2169
2170        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2171
2172        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2173        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2174
2175        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2176
2177        // User 0 is the first and only user that runs at boot.
2178        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2179        mUserLru.add(Integer.valueOf(0));
2180        updateStartedUserArrayLocked();
2181
2182        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2183            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2184
2185        mConfiguration.setToDefaults();
2186        mConfiguration.setLocale(Locale.getDefault());
2187
2188        mConfigurationSeq = mConfiguration.seq = 1;
2189        mProcessCpuTracker.init();
2190
2191        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2192        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2193        mStackSupervisor = new ActivityStackSupervisor(this);
2194        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2195
2196        mProcessCpuThread = new Thread("CpuTracker") {
2197            @Override
2198            public void run() {
2199                while (true) {
2200                    try {
2201                        try {
2202                            synchronized(this) {
2203                                final long now = SystemClock.uptimeMillis();
2204                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2205                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2206                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2207                                //        + ", write delay=" + nextWriteDelay);
2208                                if (nextWriteDelay < nextCpuDelay) {
2209                                    nextCpuDelay = nextWriteDelay;
2210                                }
2211                                if (nextCpuDelay > 0) {
2212                                    mProcessCpuMutexFree.set(true);
2213                                    this.wait(nextCpuDelay);
2214                                }
2215                            }
2216                        } catch (InterruptedException e) {
2217                        }
2218                        updateCpuStatsNow();
2219                    } catch (Exception e) {
2220                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2221                    }
2222                }
2223            }
2224        };
2225
2226        Watchdog.getInstance().addMonitor(this);
2227        Watchdog.getInstance().addThread(mHandler);
2228    }
2229
2230    public void setSystemServiceManager(SystemServiceManager mgr) {
2231        mSystemServiceManager = mgr;
2232    }
2233
2234    private void start() {
2235        mProcessCpuThread.start();
2236
2237        mBatteryStatsService.publish(mContext);
2238        mUsageStatsService.publish(mContext);
2239        mAppOpsService.publish(mContext);
2240        Slog.d("AppOps", "AppOpsService published");
2241        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2242    }
2243
2244    public void initPowerManagement() {
2245        mStackSupervisor.initPowerManagement();
2246        mBatteryStatsService.initPowerManagement();
2247    }
2248
2249    @Override
2250    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2251            throws RemoteException {
2252        if (code == SYSPROPS_TRANSACTION) {
2253            // We need to tell all apps about the system property change.
2254            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2255            synchronized(this) {
2256                final int NP = mProcessNames.getMap().size();
2257                for (int ip=0; ip<NP; ip++) {
2258                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2259                    final int NA = apps.size();
2260                    for (int ia=0; ia<NA; ia++) {
2261                        ProcessRecord app = apps.valueAt(ia);
2262                        if (app.thread != null) {
2263                            procs.add(app.thread.asBinder());
2264                        }
2265                    }
2266                }
2267            }
2268
2269            int N = procs.size();
2270            for (int i=0; i<N; i++) {
2271                Parcel data2 = Parcel.obtain();
2272                try {
2273                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2274                } catch (RemoteException e) {
2275                }
2276                data2.recycle();
2277            }
2278        }
2279        try {
2280            return super.onTransact(code, data, reply, flags);
2281        } catch (RuntimeException e) {
2282            // The activity manager only throws security exceptions, so let's
2283            // log all others.
2284            if (!(e instanceof SecurityException)) {
2285                Slog.wtf(TAG, "Activity Manager Crash", e);
2286            }
2287            throw e;
2288        }
2289    }
2290
2291    void updateCpuStats() {
2292        final long now = SystemClock.uptimeMillis();
2293        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2294            return;
2295        }
2296        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2297            synchronized (mProcessCpuThread) {
2298                mProcessCpuThread.notify();
2299            }
2300        }
2301    }
2302
2303    void updateCpuStatsNow() {
2304        synchronized (mProcessCpuThread) {
2305            mProcessCpuMutexFree.set(false);
2306            final long now = SystemClock.uptimeMillis();
2307            boolean haveNewCpuStats = false;
2308
2309            if (MONITOR_CPU_USAGE &&
2310                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2311                mLastCpuTime.set(now);
2312                haveNewCpuStats = true;
2313                mProcessCpuTracker.update();
2314                //Slog.i(TAG, mProcessCpu.printCurrentState());
2315                //Slog.i(TAG, "Total CPU usage: "
2316                //        + mProcessCpu.getTotalCpuPercent() + "%");
2317
2318                // Slog the cpu usage if the property is set.
2319                if ("true".equals(SystemProperties.get("events.cpu"))) {
2320                    int user = mProcessCpuTracker.getLastUserTime();
2321                    int system = mProcessCpuTracker.getLastSystemTime();
2322                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2323                    int irq = mProcessCpuTracker.getLastIrqTime();
2324                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2325                    int idle = mProcessCpuTracker.getLastIdleTime();
2326
2327                    int total = user + system + iowait + irq + softIrq + idle;
2328                    if (total == 0) total = 1;
2329
2330                    EventLog.writeEvent(EventLogTags.CPU,
2331                            ((user+system+iowait+irq+softIrq) * 100) / total,
2332                            (user * 100) / total,
2333                            (system * 100) / total,
2334                            (iowait * 100) / total,
2335                            (irq * 100) / total,
2336                            (softIrq * 100) / total);
2337                }
2338            }
2339
2340            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2341            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2342            synchronized(bstats) {
2343                synchronized(mPidsSelfLocked) {
2344                    if (haveNewCpuStats) {
2345                        if (mOnBattery) {
2346                            int perc = bstats.startAddingCpuLocked();
2347                            int totalUTime = 0;
2348                            int totalSTime = 0;
2349                            final int N = mProcessCpuTracker.countStats();
2350                            for (int i=0; i<N; i++) {
2351                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2352                                if (!st.working) {
2353                                    continue;
2354                                }
2355                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2356                                int otherUTime = (st.rel_utime*perc)/100;
2357                                int otherSTime = (st.rel_stime*perc)/100;
2358                                totalUTime += otherUTime;
2359                                totalSTime += otherSTime;
2360                                if (pr != null) {
2361                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2362                                    if (ps == null || !ps.isActive()) {
2363                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2364                                                pr.info.uid, pr.processName);
2365                                    }
2366                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2367                                            st.rel_stime-otherSTime);
2368                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2369                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2370                                } else {
2371                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2372                                    if (ps == null || !ps.isActive()) {
2373                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2374                                                bstats.mapUid(st.uid), st.name);
2375                                    }
2376                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2377                                            st.rel_stime-otherSTime);
2378                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2379                                }
2380                            }
2381                            bstats.finishAddingCpuLocked(perc, totalUTime,
2382                                    totalSTime, cpuSpeedTimes);
2383                        }
2384                    }
2385                }
2386
2387                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2388                    mLastWriteTime = now;
2389                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2390                }
2391            }
2392        }
2393    }
2394
2395    @Override
2396    public void batteryNeedsCpuUpdate() {
2397        updateCpuStatsNow();
2398    }
2399
2400    @Override
2401    public void batteryPowerChanged(boolean onBattery) {
2402        // When plugging in, update the CPU stats first before changing
2403        // the plug state.
2404        updateCpuStatsNow();
2405        synchronized (this) {
2406            synchronized(mPidsSelfLocked) {
2407                mOnBattery = DEBUG_POWER ? true : onBattery;
2408            }
2409        }
2410    }
2411
2412    /**
2413     * Initialize the application bind args. These are passed to each
2414     * process when the bindApplication() IPC is sent to the process. They're
2415     * lazily setup to make sure the services are running when they're asked for.
2416     */
2417    private HashMap<String, IBinder> getCommonServicesLocked() {
2418        if (mAppBindArgs == null) {
2419            mAppBindArgs = new HashMap<String, IBinder>();
2420
2421            // Setup the application init args
2422            mAppBindArgs.put("package", ServiceManager.getService("package"));
2423            mAppBindArgs.put("window", ServiceManager.getService("window"));
2424            mAppBindArgs.put(Context.ALARM_SERVICE,
2425                    ServiceManager.getService(Context.ALARM_SERVICE));
2426        }
2427        return mAppBindArgs;
2428    }
2429
2430    final void setFocusedActivityLocked(ActivityRecord r) {
2431        if (mFocusedActivity != r) {
2432            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2433            mFocusedActivity = r;
2434            if (r.task != null && r.task.voiceInteractor != null) {
2435                startRunningVoiceLocked();
2436            } else {
2437                finishRunningVoiceLocked();
2438            }
2439            mStackSupervisor.setFocusedStack(r);
2440            if (r != null) {
2441                mWindowManager.setFocusedApp(r.appToken, true);
2442            }
2443            applyUpdateLockStateLocked(r);
2444        }
2445    }
2446
2447    final void clearFocusedActivity(ActivityRecord r) {
2448        if (mFocusedActivity == r) {
2449            mFocusedActivity = null;
2450        }
2451    }
2452
2453    @Override
2454    public void setFocusedStack(int stackId) {
2455        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2456        synchronized (ActivityManagerService.this) {
2457            ActivityStack stack = mStackSupervisor.getStack(stackId);
2458            if (stack != null) {
2459                ActivityRecord r = stack.topRunningActivityLocked(null);
2460                if (r != null) {
2461                    setFocusedActivityLocked(r);
2462                }
2463            }
2464        }
2465    }
2466
2467    @Override
2468    public void notifyActivityDrawn(IBinder token) {
2469        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2470        synchronized (this) {
2471            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2472            if (r != null) {
2473                r.task.stack.notifyActivityDrawnLocked(r);
2474            }
2475        }
2476    }
2477
2478    final void applyUpdateLockStateLocked(ActivityRecord r) {
2479        // Modifications to the UpdateLock state are done on our handler, outside
2480        // the activity manager's locks.  The new state is determined based on the
2481        // state *now* of the relevant activity record.  The object is passed to
2482        // the handler solely for logging detail, not to be consulted/modified.
2483        final boolean nextState = r != null && r.immersive;
2484        mHandler.sendMessage(
2485                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2486    }
2487
2488    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2489        Message msg = Message.obtain();
2490        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2491        msg.obj = r.task.askedCompatMode ? null : r;
2492        mHandler.sendMessage(msg);
2493    }
2494
2495    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2496            String what, Object obj, ProcessRecord srcApp) {
2497        app.lastActivityTime = now;
2498
2499        if (app.activities.size() > 0) {
2500            // Don't want to touch dependent processes that are hosting activities.
2501            return index;
2502        }
2503
2504        int lrui = mLruProcesses.lastIndexOf(app);
2505        if (lrui < 0) {
2506            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2507                    + what + " " + obj + " from " + srcApp);
2508            return index;
2509        }
2510
2511        if (lrui >= index) {
2512            // Don't want to cause this to move dependent processes *back* in the
2513            // list as if they were less frequently used.
2514            return index;
2515        }
2516
2517        if (lrui >= mLruProcessActivityStart) {
2518            // Don't want to touch dependent processes that are hosting activities.
2519            return index;
2520        }
2521
2522        mLruProcesses.remove(lrui);
2523        if (index > 0) {
2524            index--;
2525        }
2526        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2527                + " in LRU list: " + app);
2528        mLruProcesses.add(index, app);
2529        return index;
2530    }
2531
2532    final void removeLruProcessLocked(ProcessRecord app) {
2533        int lrui = mLruProcesses.lastIndexOf(app);
2534        if (lrui >= 0) {
2535            if (lrui <= mLruProcessActivityStart) {
2536                mLruProcessActivityStart--;
2537            }
2538            if (lrui <= mLruProcessServiceStart) {
2539                mLruProcessServiceStart--;
2540            }
2541            mLruProcesses.remove(lrui);
2542        }
2543    }
2544
2545    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2546            ProcessRecord client) {
2547        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2548                || app.treatLikeActivity;
2549        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2550        if (!activityChange && hasActivity) {
2551            // The process has activities, so we are only allowing activity-based adjustments
2552            // to move it.  It should be kept in the front of the list with other
2553            // processes that have activities, and we don't want those to change their
2554            // order except due to activity operations.
2555            return;
2556        }
2557
2558        mLruSeq++;
2559        final long now = SystemClock.uptimeMillis();
2560        app.lastActivityTime = now;
2561
2562        // First a quick reject: if the app is already at the position we will
2563        // put it, then there is nothing to do.
2564        if (hasActivity) {
2565            final int N = mLruProcesses.size();
2566            if (N > 0 && mLruProcesses.get(N-1) == app) {
2567                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2568                return;
2569            }
2570        } else {
2571            if (mLruProcessServiceStart > 0
2572                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2573                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2574                return;
2575            }
2576        }
2577
2578        int lrui = mLruProcesses.lastIndexOf(app);
2579
2580        if (app.persistent && lrui >= 0) {
2581            // We don't care about the position of persistent processes, as long as
2582            // they are in the list.
2583            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2584            return;
2585        }
2586
2587        /* In progress: compute new position first, so we can avoid doing work
2588           if the process is not actually going to move.  Not yet working.
2589        int addIndex;
2590        int nextIndex;
2591        boolean inActivity = false, inService = false;
2592        if (hasActivity) {
2593            // Process has activities, put it at the very tipsy-top.
2594            addIndex = mLruProcesses.size();
2595            nextIndex = mLruProcessServiceStart;
2596            inActivity = true;
2597        } else if (hasService) {
2598            // Process has services, put it at the top of the service list.
2599            addIndex = mLruProcessActivityStart;
2600            nextIndex = mLruProcessServiceStart;
2601            inActivity = true;
2602            inService = true;
2603        } else  {
2604            // Process not otherwise of interest, it goes to the top of the non-service area.
2605            addIndex = mLruProcessServiceStart;
2606            if (client != null) {
2607                int clientIndex = mLruProcesses.lastIndexOf(client);
2608                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2609                        + app);
2610                if (clientIndex >= 0 && addIndex > clientIndex) {
2611                    addIndex = clientIndex;
2612                }
2613            }
2614            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2615        }
2616
2617        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2618                + mLruProcessActivityStart + "): " + app);
2619        */
2620
2621        if (lrui >= 0) {
2622            if (lrui < mLruProcessActivityStart) {
2623                mLruProcessActivityStart--;
2624            }
2625            if (lrui < mLruProcessServiceStart) {
2626                mLruProcessServiceStart--;
2627            }
2628            /*
2629            if (addIndex > lrui) {
2630                addIndex--;
2631            }
2632            if (nextIndex > lrui) {
2633                nextIndex--;
2634            }
2635            */
2636            mLruProcesses.remove(lrui);
2637        }
2638
2639        /*
2640        mLruProcesses.add(addIndex, app);
2641        if (inActivity) {
2642            mLruProcessActivityStart++;
2643        }
2644        if (inService) {
2645            mLruProcessActivityStart++;
2646        }
2647        */
2648
2649        int nextIndex;
2650        if (hasActivity) {
2651            final int N = mLruProcesses.size();
2652            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2653                // Process doesn't have activities, but has clients with
2654                // activities...  move it up, but one below the top (the top
2655                // should always have a real activity).
2656                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2657                mLruProcesses.add(N-1, app);
2658                // To keep it from spamming the LRU list (by making a bunch of clients),
2659                // we will push down any other entries owned by the app.
2660                final int uid = app.info.uid;
2661                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2662                    ProcessRecord subProc = mLruProcesses.get(i);
2663                    if (subProc.info.uid == uid) {
2664                        // We want to push this one down the list.  If the process after
2665                        // it is for the same uid, however, don't do so, because we don't
2666                        // want them internally to be re-ordered.
2667                        if (mLruProcesses.get(i-1).info.uid != uid) {
2668                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2669                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2670                            ProcessRecord tmp = mLruProcesses.get(i);
2671                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2672                            mLruProcesses.set(i-1, tmp);
2673                            i--;
2674                        }
2675                    } else {
2676                        // A gap, we can stop here.
2677                        break;
2678                    }
2679                }
2680            } else {
2681                // Process has activities, put it at the very tipsy-top.
2682                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2683                mLruProcesses.add(app);
2684            }
2685            nextIndex = mLruProcessServiceStart;
2686        } else if (hasService) {
2687            // Process has services, put it at the top of the service list.
2688            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2689            mLruProcesses.add(mLruProcessActivityStart, app);
2690            nextIndex = mLruProcessServiceStart;
2691            mLruProcessActivityStart++;
2692        } else  {
2693            // Process not otherwise of interest, it goes to the top of the non-service area.
2694            int index = mLruProcessServiceStart;
2695            if (client != null) {
2696                // If there is a client, don't allow the process to be moved up higher
2697                // in the list than that client.
2698                int clientIndex = mLruProcesses.lastIndexOf(client);
2699                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2700                        + " when updating " + app);
2701                if (clientIndex <= lrui) {
2702                    // Don't allow the client index restriction to push it down farther in the
2703                    // list than it already is.
2704                    clientIndex = lrui;
2705                }
2706                if (clientIndex >= 0 && index > clientIndex) {
2707                    index = clientIndex;
2708                }
2709            }
2710            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2711            mLruProcesses.add(index, app);
2712            nextIndex = index-1;
2713            mLruProcessActivityStart++;
2714            mLruProcessServiceStart++;
2715        }
2716
2717        // If the app is currently using a content provider or service,
2718        // bump those processes as well.
2719        for (int j=app.connections.size()-1; j>=0; j--) {
2720            ConnectionRecord cr = app.connections.valueAt(j);
2721            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2722                    && cr.binding.service.app != null
2723                    && cr.binding.service.app.lruSeq != mLruSeq
2724                    && !cr.binding.service.app.persistent) {
2725                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2726                        "service connection", cr, app);
2727            }
2728        }
2729        for (int j=app.conProviders.size()-1; j>=0; j--) {
2730            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2731            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2732                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2733                        "provider reference", cpr, app);
2734            }
2735        }
2736    }
2737
2738    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2739        if (uid == Process.SYSTEM_UID) {
2740            // The system gets to run in any process.  If there are multiple
2741            // processes with the same uid, just pick the first (this
2742            // should never happen).
2743            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2744            if (procs == null) return null;
2745            final int N = procs.size();
2746            for (int i = 0; i < N; i++) {
2747                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2748            }
2749        }
2750        ProcessRecord proc = mProcessNames.get(processName, uid);
2751        if (false && proc != null && !keepIfLarge
2752                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2753                && proc.lastCachedPss >= 4000) {
2754            // Turn this condition on to cause killing to happen regularly, for testing.
2755            if (proc.baseProcessTracker != null) {
2756                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2757            }
2758            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2759                    + "k from cached");
2760        } else if (proc != null && !keepIfLarge
2761                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2762                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2763            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2764            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2765                if (proc.baseProcessTracker != null) {
2766                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2767                }
2768                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2769                        + "k from cached");
2770            }
2771        }
2772        return proc;
2773    }
2774
2775    void ensurePackageDexOpt(String packageName) {
2776        IPackageManager pm = AppGlobals.getPackageManager();
2777        try {
2778            if (pm.performDexOpt(packageName)) {
2779                mDidDexOpt = true;
2780            }
2781        } catch (RemoteException e) {
2782        }
2783    }
2784
2785    boolean isNextTransitionForward() {
2786        int transit = mWindowManager.getPendingAppTransition();
2787        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2788                || transit == AppTransition.TRANSIT_TASK_OPEN
2789                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2790    }
2791
2792    final ProcessRecord startProcessLocked(String processName,
2793            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2794            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2795            boolean isolated, boolean keepIfLarge) {
2796        ProcessRecord app;
2797        if (!isolated) {
2798            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2799        } else {
2800            // If this is an isolated process, it can't re-use an existing process.
2801            app = null;
2802        }
2803        // We don't have to do anything more if:
2804        // (1) There is an existing application record; and
2805        // (2) The caller doesn't think it is dead, OR there is no thread
2806        //     object attached to it so we know it couldn't have crashed; and
2807        // (3) There is a pid assigned to it, so it is either starting or
2808        //     already running.
2809        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2810                + " app=" + app + " knownToBeDead=" + knownToBeDead
2811                + " thread=" + (app != null ? app.thread : null)
2812                + " pid=" + (app != null ? app.pid : -1));
2813        if (app != null && app.pid > 0) {
2814            if (!knownToBeDead || app.thread == null) {
2815                // We already have the app running, or are waiting for it to
2816                // come up (we have a pid but not yet its thread), so keep it.
2817                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2818                // If this is a new package in the process, add the package to the list
2819                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2820                return app;
2821            }
2822
2823            // An application record is attached to a previous process,
2824            // clean it up now.
2825            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2826            handleAppDiedLocked(app, true, true);
2827        }
2828
2829        String hostingNameStr = hostingName != null
2830                ? hostingName.flattenToShortString() : null;
2831
2832        if (!isolated) {
2833            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2834                // If we are in the background, then check to see if this process
2835                // is bad.  If so, we will just silently fail.
2836                if (mBadProcesses.get(info.processName, info.uid) != null) {
2837                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2838                            + "/" + info.processName);
2839                    return null;
2840                }
2841            } else {
2842                // When the user is explicitly starting a process, then clear its
2843                // crash count so that we won't make it bad until they see at
2844                // least one crash dialog again, and make the process good again
2845                // if it had been bad.
2846                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2847                        + "/" + info.processName);
2848                mProcessCrashTimes.remove(info.processName, info.uid);
2849                if (mBadProcesses.get(info.processName, info.uid) != null) {
2850                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2851                            UserHandle.getUserId(info.uid), info.uid,
2852                            info.processName);
2853                    mBadProcesses.remove(info.processName, info.uid);
2854                    if (app != null) {
2855                        app.bad = false;
2856                    }
2857                }
2858            }
2859        }
2860
2861        if (app == null) {
2862            app = newProcessRecordLocked(info, processName, isolated);
2863            if (app == null) {
2864                Slog.w(TAG, "Failed making new process record for "
2865                        + processName + "/" + info.uid + " isolated=" + isolated);
2866                return null;
2867            }
2868            mProcessNames.put(processName, app.uid, app);
2869            if (isolated) {
2870                mIsolatedProcesses.put(app.uid, app);
2871            }
2872        } else {
2873            // If this is a new package in the process, add the package to the list
2874            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2875        }
2876
2877        // If the system is not ready yet, then hold off on starting this
2878        // process until it is.
2879        if (!mProcessesReady
2880                && !isAllowedWhileBooting(info)
2881                && !allowWhileBooting) {
2882            if (!mProcessesOnHold.contains(app)) {
2883                mProcessesOnHold.add(app);
2884            }
2885            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2886            return app;
2887        }
2888
2889        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2890        return (app.pid != 0) ? app : null;
2891    }
2892
2893    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2894        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2895    }
2896
2897    private final void startProcessLocked(ProcessRecord app,
2898            String hostingType, String hostingNameStr, String abiOverride) {
2899        if (app.pid > 0 && app.pid != MY_PID) {
2900            synchronized (mPidsSelfLocked) {
2901                mPidsSelfLocked.remove(app.pid);
2902                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2903            }
2904            app.setPid(0);
2905        }
2906
2907        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2908                "startProcessLocked removing on hold: " + app);
2909        mProcessesOnHold.remove(app);
2910
2911        updateCpuStats();
2912
2913        try {
2914            int uid = app.uid;
2915
2916            int[] gids = null;
2917            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2918            if (!app.isolated) {
2919                int[] permGids = null;
2920                try {
2921                    final PackageManager pm = mContext.getPackageManager();
2922                    permGids = pm.getPackageGids(app.info.packageName);
2923
2924                    if (Environment.isExternalStorageEmulated()) {
2925                        if (pm.checkPermission(
2926                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2927                                app.info.packageName) == PERMISSION_GRANTED) {
2928                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2929                        } else {
2930                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2931                        }
2932                    }
2933                } catch (PackageManager.NameNotFoundException e) {
2934                    Slog.w(TAG, "Unable to retrieve gids", e);
2935                }
2936
2937                /*
2938                 * Add shared application and profile GIDs so applications can share some
2939                 * resources like shared libraries and access user-wide resources
2940                 */
2941                if (permGids == null) {
2942                    gids = new int[2];
2943                } else {
2944                    gids = new int[permGids.length + 2];
2945                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2946                }
2947                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2948                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2949            }
2950            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2951                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2952                        && mTopComponent != null
2953                        && app.processName.equals(mTopComponent.getPackageName())) {
2954                    uid = 0;
2955                }
2956                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2957                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2958                    uid = 0;
2959                }
2960            }
2961            int debugFlags = 0;
2962            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2963                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2964                // Also turn on CheckJNI for debuggable apps. It's quite
2965                // awkward to turn on otherwise.
2966                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2967            }
2968            // Run the app in safe mode if its manifest requests so or the
2969            // system is booted in safe mode.
2970            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2971                mSafeMode == true) {
2972                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2973            }
2974            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2975                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2976            }
2977            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2978                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2979            }
2980            if ("1".equals(SystemProperties.get("debug.assert"))) {
2981                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2982            }
2983
2984            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2985            if (requiredAbi == null) {
2986                requiredAbi = Build.SUPPORTED_ABIS[0];
2987            }
2988
2989            // Start the process.  It will either succeed and return a result containing
2990            // the PID of the new process, or else throw a RuntimeException.
2991            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2992                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2993                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2994
2995            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2996            synchronized (bs) {
2997                if (bs.isOnBattery()) {
2998                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2999                }
3000            }
3001
3002            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3003                    UserHandle.getUserId(uid), startResult.pid, uid,
3004                    app.processName, hostingType,
3005                    hostingNameStr != null ? hostingNameStr : "");
3006
3007            if (app.persistent) {
3008                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3009            }
3010
3011            StringBuilder buf = mStringBuilder;
3012            buf.setLength(0);
3013            buf.append("Start proc ");
3014            buf.append(app.processName);
3015            buf.append(" for ");
3016            buf.append(hostingType);
3017            if (hostingNameStr != null) {
3018                buf.append(" ");
3019                buf.append(hostingNameStr);
3020            }
3021            buf.append(": pid=");
3022            buf.append(startResult.pid);
3023            buf.append(" uid=");
3024            buf.append(uid);
3025            buf.append(" gids={");
3026            if (gids != null) {
3027                for (int gi=0; gi<gids.length; gi++) {
3028                    if (gi != 0) buf.append(", ");
3029                    buf.append(gids[gi]);
3030
3031                }
3032            }
3033            buf.append("}");
3034            if (requiredAbi != null) {
3035                buf.append(" abi=");
3036                buf.append(requiredAbi);
3037            }
3038            Slog.i(TAG, buf.toString());
3039            app.setPid(startResult.pid);
3040            app.usingWrapper = startResult.usingWrapper;
3041            app.removed = false;
3042            synchronized (mPidsSelfLocked) {
3043                this.mPidsSelfLocked.put(startResult.pid, app);
3044                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3045                msg.obj = app;
3046                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3047                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3048            }
3049            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3050                    app.processName, app.info.uid);
3051            if (app.isolated) {
3052                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3053            }
3054        } catch (RuntimeException e) {
3055            // XXX do better error recovery.
3056            app.setPid(0);
3057            Slog.e(TAG, "Failure starting process " + app.processName, e);
3058        }
3059    }
3060
3061    void updateUsageStats(ActivityRecord component, boolean resumed) {
3062        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3063        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3064        if (resumed) {
3065            mUsageStatsService.noteResumeComponent(component.realActivity);
3066            synchronized (stats) {
3067                stats.noteActivityResumedLocked(component.app.uid);
3068            }
3069        } else {
3070            mUsageStatsService.notePauseComponent(component.realActivity);
3071            synchronized (stats) {
3072                stats.noteActivityPausedLocked(component.app.uid);
3073            }
3074        }
3075    }
3076
3077    Intent getHomeIntent() {
3078        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3079        intent.setComponent(mTopComponent);
3080        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3081            intent.addCategory(Intent.CATEGORY_HOME);
3082        }
3083        return intent;
3084    }
3085
3086    boolean startHomeActivityLocked(int userId) {
3087        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3088                && mTopAction == null) {
3089            // We are running in factory test mode, but unable to find
3090            // the factory test app, so just sit around displaying the
3091            // error message and don't try to start anything.
3092            return false;
3093        }
3094        Intent intent = getHomeIntent();
3095        ActivityInfo aInfo =
3096            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3097        if (aInfo != null) {
3098            intent.setComponent(new ComponentName(
3099                    aInfo.applicationInfo.packageName, aInfo.name));
3100            // Don't do this if the home app is currently being
3101            // instrumented.
3102            aInfo = new ActivityInfo(aInfo);
3103            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3104            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3105                    aInfo.applicationInfo.uid, true);
3106            if (app == null || app.instrumentationClass == null) {
3107                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3108                mStackSupervisor.startHomeActivity(intent, aInfo);
3109            }
3110        }
3111
3112        return true;
3113    }
3114
3115    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3116        ActivityInfo ai = null;
3117        ComponentName comp = intent.getComponent();
3118        try {
3119            if (comp != null) {
3120                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3121            } else {
3122                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3123                        intent,
3124                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3125                            flags, userId);
3126
3127                if (info != null) {
3128                    ai = info.activityInfo;
3129                }
3130            }
3131        } catch (RemoteException e) {
3132            // ignore
3133        }
3134
3135        return ai;
3136    }
3137
3138    /**
3139     * Starts the "new version setup screen" if appropriate.
3140     */
3141    void startSetupActivityLocked() {
3142        // Only do this once per boot.
3143        if (mCheckedForSetup) {
3144            return;
3145        }
3146
3147        // We will show this screen if the current one is a different
3148        // version than the last one shown, and we are not running in
3149        // low-level factory test mode.
3150        final ContentResolver resolver = mContext.getContentResolver();
3151        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3152                Settings.Global.getInt(resolver,
3153                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3154            mCheckedForSetup = true;
3155
3156            // See if we should be showing the platform update setup UI.
3157            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3158            List<ResolveInfo> ris = mContext.getPackageManager()
3159                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3160
3161            // We don't allow third party apps to replace this.
3162            ResolveInfo ri = null;
3163            for (int i=0; ris != null && i<ris.size(); i++) {
3164                if ((ris.get(i).activityInfo.applicationInfo.flags
3165                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3166                    ri = ris.get(i);
3167                    break;
3168                }
3169            }
3170
3171            if (ri != null) {
3172                String vers = ri.activityInfo.metaData != null
3173                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3174                        : null;
3175                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3176                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3177                            Intent.METADATA_SETUP_VERSION);
3178                }
3179                String lastVers = Settings.Secure.getString(
3180                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3181                if (vers != null && !vers.equals(lastVers)) {
3182                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3183                    intent.setComponent(new ComponentName(
3184                            ri.activityInfo.packageName, ri.activityInfo.name));
3185                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3186                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3187                }
3188            }
3189        }
3190    }
3191
3192    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3193        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3194    }
3195
3196    void enforceNotIsolatedCaller(String caller) {
3197        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3198            throw new SecurityException("Isolated process not allowed to call " + caller);
3199        }
3200    }
3201
3202    @Override
3203    public int getFrontActivityScreenCompatMode() {
3204        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3205        synchronized (this) {
3206            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3207        }
3208    }
3209
3210    @Override
3211    public void setFrontActivityScreenCompatMode(int mode) {
3212        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3213                "setFrontActivityScreenCompatMode");
3214        synchronized (this) {
3215            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3216        }
3217    }
3218
3219    @Override
3220    public int getPackageScreenCompatMode(String packageName) {
3221        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3222        synchronized (this) {
3223            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3224        }
3225    }
3226
3227    @Override
3228    public void setPackageScreenCompatMode(String packageName, int mode) {
3229        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3230                "setPackageScreenCompatMode");
3231        synchronized (this) {
3232            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3233        }
3234    }
3235
3236    @Override
3237    public boolean getPackageAskScreenCompat(String packageName) {
3238        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3239        synchronized (this) {
3240            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3241        }
3242    }
3243
3244    @Override
3245    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3246        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3247                "setPackageAskScreenCompat");
3248        synchronized (this) {
3249            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3250        }
3251    }
3252
3253    private void dispatchProcessesChanged() {
3254        int N;
3255        synchronized (this) {
3256            N = mPendingProcessChanges.size();
3257            if (mActiveProcessChanges.length < N) {
3258                mActiveProcessChanges = new ProcessChangeItem[N];
3259            }
3260            mPendingProcessChanges.toArray(mActiveProcessChanges);
3261            mAvailProcessChanges.addAll(mPendingProcessChanges);
3262            mPendingProcessChanges.clear();
3263            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3264        }
3265
3266        int i = mProcessObservers.beginBroadcast();
3267        while (i > 0) {
3268            i--;
3269            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3270            if (observer != null) {
3271                try {
3272                    for (int j=0; j<N; j++) {
3273                        ProcessChangeItem item = mActiveProcessChanges[j];
3274                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3275                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3276                                    + item.pid + " uid=" + item.uid + ": "
3277                                    + item.foregroundActivities);
3278                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3279                                    item.foregroundActivities);
3280                        }
3281                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3282                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3283                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3284                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3285                        }
3286                    }
3287                } catch (RemoteException e) {
3288                }
3289            }
3290        }
3291        mProcessObservers.finishBroadcast();
3292    }
3293
3294    private void dispatchProcessDied(int pid, int uid) {
3295        int i = mProcessObservers.beginBroadcast();
3296        while (i > 0) {
3297            i--;
3298            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3299            if (observer != null) {
3300                try {
3301                    observer.onProcessDied(pid, uid);
3302                } catch (RemoteException e) {
3303                }
3304            }
3305        }
3306        mProcessObservers.finishBroadcast();
3307    }
3308
3309    final void doPendingActivityLaunchesLocked(boolean doResume) {
3310        final int N = mPendingActivityLaunches.size();
3311        if (N <= 0) {
3312            return;
3313        }
3314        for (int i=0; i<N; i++) {
3315            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3316            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3317                    doResume && i == (N-1), null);
3318        }
3319        mPendingActivityLaunches.clear();
3320    }
3321
3322    @Override
3323    public final int startActivity(IApplicationThread caller, String callingPackage,
3324            Intent intent, String resolvedType, IBinder resultTo,
3325            String resultWho, int requestCode, int startFlags,
3326            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3327        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3328                resultWho, requestCode,
3329                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3330    }
3331
3332    @Override
3333    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3334            Intent intent, String resolvedType, IBinder resultTo,
3335            String resultWho, int requestCode, int startFlags,
3336            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3337        enforceNotIsolatedCaller("startActivity");
3338        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3339                false, true, "startActivity", null);
3340        // TODO: Switch to user app stacks here.
3341        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3342                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3343                null, null, options, userId, null);
3344    }
3345
3346    @Override
3347    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3348            Intent intent, String resolvedType, IBinder resultTo,
3349            String resultWho, int requestCode, int startFlags, String profileFile,
3350            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3351        enforceNotIsolatedCaller("startActivityAndWait");
3352        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3353                false, true, "startActivityAndWait", null);
3354        WaitResult res = new WaitResult();
3355        // TODO: Switch to user app stacks here.
3356        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3357                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3358                res, null, options, UserHandle.getCallingUserId(), null);
3359        return res;
3360    }
3361
3362    @Override
3363    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3364            Intent intent, String resolvedType, IBinder resultTo,
3365            String resultWho, int requestCode, int startFlags, Configuration config,
3366            Bundle options, int userId) {
3367        enforceNotIsolatedCaller("startActivityWithConfig");
3368        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3369                false, true, "startActivityWithConfig", null);
3370        // TODO: Switch to user app stacks here.
3371        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3372                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3373                null, null, null, config, options, userId, null);
3374        return ret;
3375    }
3376
3377    @Override
3378    public int startActivityIntentSender(IApplicationThread caller,
3379            IntentSender intent, Intent fillInIntent, String resolvedType,
3380            IBinder resultTo, String resultWho, int requestCode,
3381            int flagsMask, int flagsValues, Bundle options) {
3382        enforceNotIsolatedCaller("startActivityIntentSender");
3383        // Refuse possible leaked file descriptors
3384        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3385            throw new IllegalArgumentException("File descriptors passed in Intent");
3386        }
3387
3388        IIntentSender sender = intent.getTarget();
3389        if (!(sender instanceof PendingIntentRecord)) {
3390            throw new IllegalArgumentException("Bad PendingIntent object");
3391        }
3392
3393        PendingIntentRecord pir = (PendingIntentRecord)sender;
3394
3395        synchronized (this) {
3396            // If this is coming from the currently resumed activity, it is
3397            // effectively saying that app switches are allowed at this point.
3398            final ActivityStack stack = getFocusedStack();
3399            if (stack.mResumedActivity != null &&
3400                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3401                mAppSwitchesAllowedTime = 0;
3402            }
3403        }
3404        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3405                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3406        return ret;
3407    }
3408
3409    @Override
3410    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3411            Intent intent, String resolvedType, IVoiceInteractionSession session,
3412            IVoiceInteractor interactor, int startFlags, String profileFile,
3413            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3414        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3415                != PackageManager.PERMISSION_GRANTED) {
3416            String msg = "Permission Denial: startVoiceActivity() from pid="
3417                    + Binder.getCallingPid()
3418                    + ", uid=" + Binder.getCallingUid()
3419                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3420            Slog.w(TAG, msg);
3421            throw new SecurityException(msg);
3422        }
3423        if (session == null || interactor == null) {
3424            throw new NullPointerException("null session or interactor");
3425        }
3426        userId = handleIncomingUser(callingPid, callingUid, userId,
3427                false, true, "startVoiceActivity", null);
3428        // TODO: Switch to user app stacks here.
3429        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3430                resolvedType, session, interactor, null, null, 0, startFlags,
3431                profileFile, profileFd, null, null, options, userId, null);
3432    }
3433
3434    @Override
3435    public boolean startNextMatchingActivity(IBinder callingActivity,
3436            Intent intent, Bundle options) {
3437        // Refuse possible leaked file descriptors
3438        if (intent != null && intent.hasFileDescriptors() == true) {
3439            throw new IllegalArgumentException("File descriptors passed in Intent");
3440        }
3441
3442        synchronized (this) {
3443            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3444            if (r == null) {
3445                ActivityOptions.abort(options);
3446                return false;
3447            }
3448            if (r.app == null || r.app.thread == null) {
3449                // The caller is not running...  d'oh!
3450                ActivityOptions.abort(options);
3451                return false;
3452            }
3453            intent = new Intent(intent);
3454            // The caller is not allowed to change the data.
3455            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3456            // And we are resetting to find the next component...
3457            intent.setComponent(null);
3458
3459            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3460
3461            ActivityInfo aInfo = null;
3462            try {
3463                List<ResolveInfo> resolves =
3464                    AppGlobals.getPackageManager().queryIntentActivities(
3465                            intent, r.resolvedType,
3466                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3467                            UserHandle.getCallingUserId());
3468
3469                // Look for the original activity in the list...
3470                final int N = resolves != null ? resolves.size() : 0;
3471                for (int i=0; i<N; i++) {
3472                    ResolveInfo rInfo = resolves.get(i);
3473                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3474                            && rInfo.activityInfo.name.equals(r.info.name)) {
3475                        // We found the current one...  the next matching is
3476                        // after it.
3477                        i++;
3478                        if (i<N) {
3479                            aInfo = resolves.get(i).activityInfo;
3480                        }
3481                        if (debug) {
3482                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3483                                    + "/" + r.info.name);
3484                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3485                                    + "/" + aInfo.name);
3486                        }
3487                        break;
3488                    }
3489                }
3490            } catch (RemoteException e) {
3491            }
3492
3493            if (aInfo == null) {
3494                // Nobody who is next!
3495                ActivityOptions.abort(options);
3496                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3497                return false;
3498            }
3499
3500            intent.setComponent(new ComponentName(
3501                    aInfo.applicationInfo.packageName, aInfo.name));
3502            intent.setFlags(intent.getFlags()&~(
3503                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3504                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3505                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3506                    Intent.FLAG_ACTIVITY_NEW_TASK));
3507
3508            // Okay now we need to start the new activity, replacing the
3509            // currently running activity.  This is a little tricky because
3510            // we want to start the new one as if the current one is finished,
3511            // but not finish the current one first so that there is no flicker.
3512            // And thus...
3513            final boolean wasFinishing = r.finishing;
3514            r.finishing = true;
3515
3516            // Propagate reply information over to the new activity.
3517            final ActivityRecord resultTo = r.resultTo;
3518            final String resultWho = r.resultWho;
3519            final int requestCode = r.requestCode;
3520            r.resultTo = null;
3521            if (resultTo != null) {
3522                resultTo.removeResultsLocked(r, resultWho, requestCode);
3523            }
3524
3525            final long origId = Binder.clearCallingIdentity();
3526            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3527                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3528                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3529                    options, false, null, null);
3530            Binder.restoreCallingIdentity(origId);
3531
3532            r.finishing = wasFinishing;
3533            if (res != ActivityManager.START_SUCCESS) {
3534                return false;
3535            }
3536            return true;
3537        }
3538    }
3539
3540    final int startActivityInPackage(int uid, String callingPackage,
3541            Intent intent, String resolvedType, IBinder resultTo,
3542            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3543                    IActivityContainer container) {
3544
3545        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3546                false, true, "startActivityInPackage", null);
3547
3548        // TODO: Switch to user app stacks here.
3549        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3550                null, null, resultTo, resultWho, requestCode, startFlags,
3551                null, null, null, null, options, userId, container);
3552        return ret;
3553    }
3554
3555    @Override
3556    public final int startActivities(IApplicationThread caller, String callingPackage,
3557            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3558            int userId) {
3559        enforceNotIsolatedCaller("startActivities");
3560        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3561                false, true, "startActivity", null);
3562        // TODO: Switch to user app stacks here.
3563        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3564                resolvedTypes, resultTo, options, userId);
3565        return ret;
3566    }
3567
3568    final int startActivitiesInPackage(int uid, String callingPackage,
3569            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3570            Bundle options, int userId) {
3571
3572        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3573                false, true, "startActivityInPackage", null);
3574        // TODO: Switch to user app stacks here.
3575        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3576                resultTo, options, userId);
3577        return ret;
3578    }
3579
3580    final void addRecentTaskLocked(TaskRecord task) {
3581        int N = mRecentTasks.size();
3582        // Quick case: check if the top-most recent task is the same.
3583        if (N > 0 && mRecentTasks.get(0) == task) {
3584            return;
3585        }
3586        // Another quick case: never add voice sessions.
3587        if (task.voiceSession != null) {
3588            return;
3589        }
3590        // Remove any existing entries that are the same kind of task.
3591        final Intent intent = task.intent;
3592        final boolean document = intent != null && intent.isDocument();
3593        final ComponentName comp = intent.getComponent();
3594
3595        int maxRecents = task.maxRecents - 1;
3596        for (int i=0; i<N; i++) {
3597            TaskRecord tr = mRecentTasks.get(i);
3598            if (task != tr) {
3599                if (task.userId != tr.userId) {
3600                    continue;
3601                }
3602                final Intent trIntent = tr.intent;
3603                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3604                    (intent == null || !intent.filterEquals(trIntent))) {
3605                    continue;
3606                }
3607                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3608                if (document && trIsDocument) {
3609                    // These are the same document activity (not necessarily the same doc).
3610                    if (maxRecents > 0) {
3611                        --maxRecents;
3612                        continue;
3613                    }
3614                    // Hit the maximum number of documents for this task. Fall through
3615                    // and remove this document from recents.
3616                } else if (document || trIsDocument) {
3617                    // Only one of these is a document. Not the droid we're looking for.
3618                    continue;
3619                }
3620            }
3621
3622            // Either task and tr are the same or, their affinities match or their intents match
3623            // and neither of them is a document, or they are documents using the same activity
3624            // and their maxRecents has been reached.
3625            tr.disposeThumbnail();
3626            mRecentTasks.remove(i);
3627            i--;
3628            N--;
3629            if (task.intent == null) {
3630                // If the new recent task we are adding is not fully
3631                // specified, then replace it with the existing recent task.
3632                task = tr;
3633            }
3634            mTaskPersister.notify(tr, false);
3635        }
3636        if (N >= MAX_RECENT_TASKS) {
3637            mRecentTasks.remove(N-1).disposeThumbnail();
3638        }
3639        mRecentTasks.add(0, task);
3640    }
3641
3642    @Override
3643    public void reportActivityFullyDrawn(IBinder token) {
3644        synchronized (this) {
3645            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3646            if (r == null) {
3647                return;
3648            }
3649            r.reportFullyDrawnLocked();
3650        }
3651    }
3652
3653    @Override
3654    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3655        synchronized (this) {
3656            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3657            if (r == null) {
3658                return;
3659            }
3660            final long origId = Binder.clearCallingIdentity();
3661            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3662            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3663                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3664            if (config != null) {
3665                r.frozenBeforeDestroy = true;
3666                if (!updateConfigurationLocked(config, r, false, false)) {
3667                    mStackSupervisor.resumeTopActivitiesLocked();
3668                }
3669            }
3670            Binder.restoreCallingIdentity(origId);
3671        }
3672    }
3673
3674    @Override
3675    public int getRequestedOrientation(IBinder token) {
3676        synchronized (this) {
3677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3678            if (r == null) {
3679                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3680            }
3681            return mWindowManager.getAppOrientation(r.appToken);
3682        }
3683    }
3684
3685    /**
3686     * This is the internal entry point for handling Activity.finish().
3687     *
3688     * @param token The Binder token referencing the Activity we want to finish.
3689     * @param resultCode Result code, if any, from this Activity.
3690     * @param resultData Result data (Intent), if any, from this Activity.
3691     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3692     *            the root Activity in the task.
3693     *
3694     * @return Returns true if the activity successfully finished, or false if it is still running.
3695     */
3696    @Override
3697    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3698            boolean finishTask) {
3699        // Refuse possible leaked file descriptors
3700        if (resultData != null && resultData.hasFileDescriptors() == true) {
3701            throw new IllegalArgumentException("File descriptors passed in Intent");
3702        }
3703
3704        synchronized(this) {
3705            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3706            if (r == null) {
3707                return true;
3708            }
3709            // Keep track of the root activity of the task before we finish it
3710            TaskRecord tr = r.task;
3711            ActivityRecord rootR = tr.getRootActivity();
3712            if (mController != null) {
3713                // Find the first activity that is not finishing.
3714                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3715                if (next != null) {
3716                    // ask watcher if this is allowed
3717                    boolean resumeOK = true;
3718                    try {
3719                        resumeOK = mController.activityResuming(next.packageName);
3720                    } catch (RemoteException e) {
3721                        mController = null;
3722                        Watchdog.getInstance().setActivityController(null);
3723                    }
3724
3725                    if (!resumeOK) {
3726                        return false;
3727                    }
3728                }
3729            }
3730            final long origId = Binder.clearCallingIdentity();
3731            try {
3732                boolean res;
3733                if (finishTask && r == rootR) {
3734                    // If requested, remove the task that is associated to this activity only if it
3735                    // was the root activity in the task.  The result code and data is ignored because
3736                    // we don't support returning them across task boundaries.
3737                    res = removeTaskByIdLocked(tr.taskId, 0);
3738                } else {
3739                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3740                            resultData, "app-request", true);
3741                }
3742                return res;
3743            } finally {
3744                Binder.restoreCallingIdentity(origId);
3745            }
3746        }
3747    }
3748
3749    @Override
3750    public final void finishHeavyWeightApp() {
3751        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3752                != PackageManager.PERMISSION_GRANTED) {
3753            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3754                    + Binder.getCallingPid()
3755                    + ", uid=" + Binder.getCallingUid()
3756                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3757            Slog.w(TAG, msg);
3758            throw new SecurityException(msg);
3759        }
3760
3761        synchronized(this) {
3762            if (mHeavyWeightProcess == null) {
3763                return;
3764            }
3765
3766            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3767                    mHeavyWeightProcess.activities);
3768            for (int i=0; i<activities.size(); i++) {
3769                ActivityRecord r = activities.get(i);
3770                if (!r.finishing) {
3771                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3772                            null, "finish-heavy", true);
3773                }
3774            }
3775
3776            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3777                    mHeavyWeightProcess.userId, 0));
3778            mHeavyWeightProcess = null;
3779        }
3780    }
3781
3782    @Override
3783    public void crashApplication(int uid, int initialPid, String packageName,
3784            String message) {
3785        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3786                != PackageManager.PERMISSION_GRANTED) {
3787            String msg = "Permission Denial: crashApplication() from pid="
3788                    + Binder.getCallingPid()
3789                    + ", uid=" + Binder.getCallingUid()
3790                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3791            Slog.w(TAG, msg);
3792            throw new SecurityException(msg);
3793        }
3794
3795        synchronized(this) {
3796            ProcessRecord proc = null;
3797
3798            // Figure out which process to kill.  We don't trust that initialPid
3799            // still has any relation to current pids, so must scan through the
3800            // list.
3801            synchronized (mPidsSelfLocked) {
3802                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3803                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3804                    if (p.uid != uid) {
3805                        continue;
3806                    }
3807                    if (p.pid == initialPid) {
3808                        proc = p;
3809                        break;
3810                    }
3811                    if (p.pkgList.containsKey(packageName)) {
3812                        proc = p;
3813                    }
3814                }
3815            }
3816
3817            if (proc == null) {
3818                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3819                        + " initialPid=" + initialPid
3820                        + " packageName=" + packageName);
3821                return;
3822            }
3823
3824            if (proc.thread != null) {
3825                if (proc.pid == Process.myPid()) {
3826                    Log.w(TAG, "crashApplication: trying to crash self!");
3827                    return;
3828                }
3829                long ident = Binder.clearCallingIdentity();
3830                try {
3831                    proc.thread.scheduleCrash(message);
3832                } catch (RemoteException e) {
3833                }
3834                Binder.restoreCallingIdentity(ident);
3835            }
3836        }
3837    }
3838
3839    @Override
3840    public final void finishSubActivity(IBinder token, String resultWho,
3841            int requestCode) {
3842        synchronized(this) {
3843            final long origId = Binder.clearCallingIdentity();
3844            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3845            if (r != null) {
3846                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3847            }
3848            Binder.restoreCallingIdentity(origId);
3849        }
3850    }
3851
3852    @Override
3853    public boolean finishActivityAffinity(IBinder token) {
3854        synchronized(this) {
3855            final long origId = Binder.clearCallingIdentity();
3856            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3857            boolean res = false;
3858            if (r != null) {
3859                res = r.task.stack.finishActivityAffinityLocked(r);
3860            }
3861            Binder.restoreCallingIdentity(origId);
3862            return res;
3863        }
3864    }
3865
3866    @Override
3867    public boolean willActivityBeVisible(IBinder token) {
3868        synchronized(this) {
3869            ActivityStack stack = ActivityRecord.getStackLocked(token);
3870            if (stack != null) {
3871                return stack.willActivityBeVisibleLocked(token);
3872            }
3873            return false;
3874        }
3875    }
3876
3877    @Override
3878    public void overridePendingTransition(IBinder token, String packageName,
3879            int enterAnim, int exitAnim) {
3880        synchronized(this) {
3881            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3882            if (self == null) {
3883                return;
3884            }
3885
3886            final long origId = Binder.clearCallingIdentity();
3887
3888            if (self.state == ActivityState.RESUMED
3889                    || self.state == ActivityState.PAUSING) {
3890                mWindowManager.overridePendingAppTransition(packageName,
3891                        enterAnim, exitAnim, null);
3892            }
3893
3894            Binder.restoreCallingIdentity(origId);
3895        }
3896    }
3897
3898    /**
3899     * Main function for removing an existing process from the activity manager
3900     * as a result of that process going away.  Clears out all connections
3901     * to the process.
3902     */
3903    private final void handleAppDiedLocked(ProcessRecord app,
3904            boolean restarting, boolean allowRestart) {
3905        int pid = app.pid;
3906        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3907        if (!restarting) {
3908            removeLruProcessLocked(app);
3909            if (pid > 0) {
3910                ProcessList.remove(pid);
3911            }
3912        }
3913
3914        if (mProfileProc == app) {
3915            clearProfilerLocked();
3916        }
3917
3918        // Remove this application's activities from active lists.
3919        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3920
3921        app.activities.clear();
3922
3923        if (app.instrumentationClass != null) {
3924            Slog.w(TAG, "Crash of app " + app.processName
3925                  + " running instrumentation " + app.instrumentationClass);
3926            Bundle info = new Bundle();
3927            info.putString("shortMsg", "Process crashed.");
3928            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3929        }
3930
3931        if (!restarting) {
3932            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3933                // If there was nothing to resume, and we are not already
3934                // restarting this process, but there is a visible activity that
3935                // is hosted by the process...  then make sure all visible
3936                // activities are running, taking care of restarting this
3937                // process.
3938                if (hasVisibleActivities) {
3939                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3940                }
3941            }
3942        }
3943    }
3944
3945    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3946        IBinder threadBinder = thread.asBinder();
3947        // Find the application record.
3948        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3949            ProcessRecord rec = mLruProcesses.get(i);
3950            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3951                return i;
3952            }
3953        }
3954        return -1;
3955    }
3956
3957    final ProcessRecord getRecordForAppLocked(
3958            IApplicationThread thread) {
3959        if (thread == null) {
3960            return null;
3961        }
3962
3963        int appIndex = getLRURecordIndexForAppLocked(thread);
3964        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3965    }
3966
3967    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3968        // If there are no longer any background processes running,
3969        // and the app that died was not running instrumentation,
3970        // then tell everyone we are now low on memory.
3971        boolean haveBg = false;
3972        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3973            ProcessRecord rec = mLruProcesses.get(i);
3974            if (rec.thread != null
3975                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3976                haveBg = true;
3977                break;
3978            }
3979        }
3980
3981        if (!haveBg) {
3982            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3983            if (doReport) {
3984                long now = SystemClock.uptimeMillis();
3985                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3986                    doReport = false;
3987                } else {
3988                    mLastMemUsageReportTime = now;
3989                }
3990            }
3991            final ArrayList<ProcessMemInfo> memInfos
3992                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3993            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3994            long now = SystemClock.uptimeMillis();
3995            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3996                ProcessRecord rec = mLruProcesses.get(i);
3997                if (rec == dyingProc || rec.thread == null) {
3998                    continue;
3999                }
4000                if (doReport) {
4001                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4002                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4003                }
4004                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4005                    // The low memory report is overriding any current
4006                    // state for a GC request.  Make sure to do
4007                    // heavy/important/visible/foreground processes first.
4008                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4009                        rec.lastRequestedGc = 0;
4010                    } else {
4011                        rec.lastRequestedGc = rec.lastLowMemory;
4012                    }
4013                    rec.reportLowMemory = true;
4014                    rec.lastLowMemory = now;
4015                    mProcessesToGc.remove(rec);
4016                    addProcessToGcListLocked(rec);
4017                }
4018            }
4019            if (doReport) {
4020                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4021                mHandler.sendMessage(msg);
4022            }
4023            scheduleAppGcsLocked();
4024        }
4025    }
4026
4027    final void appDiedLocked(ProcessRecord app, int pid,
4028            IApplicationThread thread) {
4029
4030        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4031        synchronized (stats) {
4032            stats.noteProcessDiedLocked(app.info.uid, pid);
4033        }
4034
4035        // Clean up already done if the process has been re-started.
4036        if (app.pid == pid && app.thread != null &&
4037                app.thread.asBinder() == thread.asBinder()) {
4038            boolean doLowMem = app.instrumentationClass == null;
4039            boolean doOomAdj = doLowMem;
4040            if (!app.killedByAm) {
4041                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4042                        + ") has died.");
4043                mAllowLowerMemLevel = true;
4044            } else {
4045                // Note that we always want to do oom adj to update our state with the
4046                // new number of procs.
4047                mAllowLowerMemLevel = false;
4048                doLowMem = false;
4049            }
4050            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4051            if (DEBUG_CLEANUP) Slog.v(
4052                TAG, "Dying app: " + app + ", pid: " + pid
4053                + ", thread: " + thread.asBinder());
4054            handleAppDiedLocked(app, false, true);
4055
4056            if (doOomAdj) {
4057                updateOomAdjLocked();
4058            }
4059            if (doLowMem) {
4060                doLowMemReportIfNeededLocked(app);
4061            }
4062        } else if (app.pid != pid) {
4063            // A new process has already been started.
4064            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4065                    + ") has died and restarted (pid " + app.pid + ").");
4066            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4067        } else if (DEBUG_PROCESSES) {
4068            Slog.d(TAG, "Received spurious death notification for thread "
4069                    + thread.asBinder());
4070        }
4071    }
4072
4073    /**
4074     * If a stack trace dump file is configured, dump process stack traces.
4075     * @param clearTraces causes the dump file to be erased prior to the new
4076     *    traces being written, if true; when false, the new traces will be
4077     *    appended to any existing file content.
4078     * @param firstPids of dalvik VM processes to dump stack traces for first
4079     * @param lastPids of dalvik VM processes to dump stack traces for last
4080     * @param nativeProcs optional list of native process names to dump stack crawls
4081     * @return file containing stack traces, or null if no dump file is configured
4082     */
4083    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4084            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4085        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4086        if (tracesPath == null || tracesPath.length() == 0) {
4087            return null;
4088        }
4089
4090        File tracesFile = new File(tracesPath);
4091        try {
4092            File tracesDir = tracesFile.getParentFile();
4093            if (!tracesDir.exists()) {
4094                tracesFile.mkdirs();
4095                if (!SELinux.restorecon(tracesDir)) {
4096                    return null;
4097                }
4098            }
4099            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4100
4101            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4102            tracesFile.createNewFile();
4103            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4104        } catch (IOException e) {
4105            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4106            return null;
4107        }
4108
4109        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4110        return tracesFile;
4111    }
4112
4113    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4114            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4115        // Use a FileObserver to detect when traces finish writing.
4116        // The order of traces is considered important to maintain for legibility.
4117        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4118            @Override
4119            public synchronized void onEvent(int event, String path) { notify(); }
4120        };
4121
4122        try {
4123            observer.startWatching();
4124
4125            // First collect all of the stacks of the most important pids.
4126            if (firstPids != null) {
4127                try {
4128                    int num = firstPids.size();
4129                    for (int i = 0; i < num; i++) {
4130                        synchronized (observer) {
4131                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4132                            observer.wait(200);  // Wait for write-close, give up after 200msec
4133                        }
4134                    }
4135                } catch (InterruptedException e) {
4136                    Log.wtf(TAG, e);
4137                }
4138            }
4139
4140            // Next collect the stacks of the native pids
4141            if (nativeProcs != null) {
4142                int[] pids = Process.getPidsForCommands(nativeProcs);
4143                if (pids != null) {
4144                    for (int pid : pids) {
4145                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4146                    }
4147                }
4148            }
4149
4150            // Lastly, measure CPU usage.
4151            if (processCpuTracker != null) {
4152                processCpuTracker.init();
4153                System.gc();
4154                processCpuTracker.update();
4155                try {
4156                    synchronized (processCpuTracker) {
4157                        processCpuTracker.wait(500); // measure over 1/2 second.
4158                    }
4159                } catch (InterruptedException e) {
4160                }
4161                processCpuTracker.update();
4162
4163                // We'll take the stack crawls of just the top apps using CPU.
4164                final int N = processCpuTracker.countWorkingStats();
4165                int numProcs = 0;
4166                for (int i=0; i<N && numProcs<5; i++) {
4167                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4168                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4169                        numProcs++;
4170                        try {
4171                            synchronized (observer) {
4172                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4173                                observer.wait(200);  // Wait for write-close, give up after 200msec
4174                            }
4175                        } catch (InterruptedException e) {
4176                            Log.wtf(TAG, e);
4177                        }
4178
4179                    }
4180                }
4181            }
4182        } finally {
4183            observer.stopWatching();
4184        }
4185    }
4186
4187    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4188        if (true || IS_USER_BUILD) {
4189            return;
4190        }
4191        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4192        if (tracesPath == null || tracesPath.length() == 0) {
4193            return;
4194        }
4195
4196        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4197        StrictMode.allowThreadDiskWrites();
4198        try {
4199            final File tracesFile = new File(tracesPath);
4200            final File tracesDir = tracesFile.getParentFile();
4201            final File tracesTmp = new File(tracesDir, "__tmp__");
4202            try {
4203                if (!tracesDir.exists()) {
4204                    tracesFile.mkdirs();
4205                    if (!SELinux.restorecon(tracesDir.getPath())) {
4206                        return;
4207                    }
4208                }
4209                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4210
4211                if (tracesFile.exists()) {
4212                    tracesTmp.delete();
4213                    tracesFile.renameTo(tracesTmp);
4214                }
4215                StringBuilder sb = new StringBuilder();
4216                Time tobj = new Time();
4217                tobj.set(System.currentTimeMillis());
4218                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4219                sb.append(": ");
4220                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4221                sb.append(" since ");
4222                sb.append(msg);
4223                FileOutputStream fos = new FileOutputStream(tracesFile);
4224                fos.write(sb.toString().getBytes());
4225                if (app == null) {
4226                    fos.write("\n*** No application process!".getBytes());
4227                }
4228                fos.close();
4229                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4230            } catch (IOException e) {
4231                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4232                return;
4233            }
4234
4235            if (app != null) {
4236                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4237                firstPids.add(app.pid);
4238                dumpStackTraces(tracesPath, firstPids, null, null, null);
4239            }
4240
4241            File lastTracesFile = null;
4242            File curTracesFile = null;
4243            for (int i=9; i>=0; i--) {
4244                String name = String.format(Locale.US, "slow%02d.txt", i);
4245                curTracesFile = new File(tracesDir, name);
4246                if (curTracesFile.exists()) {
4247                    if (lastTracesFile != null) {
4248                        curTracesFile.renameTo(lastTracesFile);
4249                    } else {
4250                        curTracesFile.delete();
4251                    }
4252                }
4253                lastTracesFile = curTracesFile;
4254            }
4255            tracesFile.renameTo(curTracesFile);
4256            if (tracesTmp.exists()) {
4257                tracesTmp.renameTo(tracesFile);
4258            }
4259        } finally {
4260            StrictMode.setThreadPolicy(oldPolicy);
4261        }
4262    }
4263
4264    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4265            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4266        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4267        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4268
4269        if (mController != null) {
4270            try {
4271                // 0 == continue, -1 = kill process immediately
4272                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4273                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4274            } catch (RemoteException e) {
4275                mController = null;
4276                Watchdog.getInstance().setActivityController(null);
4277            }
4278        }
4279
4280        long anrTime = SystemClock.uptimeMillis();
4281        if (MONITOR_CPU_USAGE) {
4282            updateCpuStatsNow();
4283        }
4284
4285        synchronized (this) {
4286            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4287            if (mShuttingDown) {
4288                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4289                return;
4290            } else if (app.notResponding) {
4291                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4292                return;
4293            } else if (app.crashing) {
4294                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4295                return;
4296            }
4297
4298            // In case we come through here for the same app before completing
4299            // this one, mark as anring now so we will bail out.
4300            app.notResponding = true;
4301
4302            // Log the ANR to the event log.
4303            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4304                    app.processName, app.info.flags, annotation);
4305
4306            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4307            firstPids.add(app.pid);
4308
4309            int parentPid = app.pid;
4310            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4311            if (parentPid != app.pid) firstPids.add(parentPid);
4312
4313            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4314
4315            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4316                ProcessRecord r = mLruProcesses.get(i);
4317                if (r != null && r.thread != null) {
4318                    int pid = r.pid;
4319                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4320                        if (r.persistent) {
4321                            firstPids.add(pid);
4322                        } else {
4323                            lastPids.put(pid, Boolean.TRUE);
4324                        }
4325                    }
4326                }
4327            }
4328        }
4329
4330        // Log the ANR to the main log.
4331        StringBuilder info = new StringBuilder();
4332        info.setLength(0);
4333        info.append("ANR in ").append(app.processName);
4334        if (activity != null && activity.shortComponentName != null) {
4335            info.append(" (").append(activity.shortComponentName).append(")");
4336        }
4337        info.append("\n");
4338        info.append("PID: ").append(app.pid).append("\n");
4339        if (annotation != null) {
4340            info.append("Reason: ").append(annotation).append("\n");
4341        }
4342        if (parent != null && parent != activity) {
4343            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4344        }
4345
4346        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4347
4348        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4349                NATIVE_STACKS_OF_INTEREST);
4350
4351        String cpuInfo = null;
4352        if (MONITOR_CPU_USAGE) {
4353            updateCpuStatsNow();
4354            synchronized (mProcessCpuThread) {
4355                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4356            }
4357            info.append(processCpuTracker.printCurrentLoad());
4358            info.append(cpuInfo);
4359        }
4360
4361        info.append(processCpuTracker.printCurrentState(anrTime));
4362
4363        Slog.e(TAG, info.toString());
4364        if (tracesFile == null) {
4365            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4366            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4367        }
4368
4369        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4370                cpuInfo, tracesFile, null);
4371
4372        if (mController != null) {
4373            try {
4374                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4375                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4376                if (res != 0) {
4377                    if (res < 0 && app.pid != MY_PID) {
4378                        Process.killProcess(app.pid);
4379                    } else {
4380                        synchronized (this) {
4381                            mServices.scheduleServiceTimeoutLocked(app);
4382                        }
4383                    }
4384                    return;
4385                }
4386            } catch (RemoteException e) {
4387                mController = null;
4388                Watchdog.getInstance().setActivityController(null);
4389            }
4390        }
4391
4392        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4393        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4394                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4395
4396        synchronized (this) {
4397            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4398                killUnneededProcessLocked(app, "background ANR");
4399                return;
4400            }
4401
4402            // Set the app's notResponding state, and look up the errorReportReceiver
4403            makeAppNotRespondingLocked(app,
4404                    activity != null ? activity.shortComponentName : null,
4405                    annotation != null ? "ANR " + annotation : "ANR",
4406                    info.toString());
4407
4408            // Bring up the infamous App Not Responding dialog
4409            Message msg = Message.obtain();
4410            HashMap<String, Object> map = new HashMap<String, Object>();
4411            msg.what = SHOW_NOT_RESPONDING_MSG;
4412            msg.obj = map;
4413            msg.arg1 = aboveSystem ? 1 : 0;
4414            map.put("app", app);
4415            if (activity != null) {
4416                map.put("activity", activity);
4417            }
4418
4419            mHandler.sendMessage(msg);
4420        }
4421    }
4422
4423    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4424        if (!mLaunchWarningShown) {
4425            mLaunchWarningShown = true;
4426            mHandler.post(new Runnable() {
4427                @Override
4428                public void run() {
4429                    synchronized (ActivityManagerService.this) {
4430                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4431                        d.show();
4432                        mHandler.postDelayed(new Runnable() {
4433                            @Override
4434                            public void run() {
4435                                synchronized (ActivityManagerService.this) {
4436                                    d.dismiss();
4437                                    mLaunchWarningShown = false;
4438                                }
4439                            }
4440                        }, 4000);
4441                    }
4442                }
4443            });
4444        }
4445    }
4446
4447    @Override
4448    public boolean clearApplicationUserData(final String packageName,
4449            final IPackageDataObserver observer, int userId) {
4450        enforceNotIsolatedCaller("clearApplicationUserData");
4451        int uid = Binder.getCallingUid();
4452        int pid = Binder.getCallingPid();
4453        userId = handleIncomingUser(pid, uid,
4454                userId, false, true, "clearApplicationUserData", null);
4455        long callingId = Binder.clearCallingIdentity();
4456        try {
4457            IPackageManager pm = AppGlobals.getPackageManager();
4458            int pkgUid = -1;
4459            synchronized(this) {
4460                try {
4461                    pkgUid = pm.getPackageUid(packageName, userId);
4462                } catch (RemoteException e) {
4463                }
4464                if (pkgUid == -1) {
4465                    Slog.w(TAG, "Invalid packageName: " + packageName);
4466                    if (observer != null) {
4467                        try {
4468                            observer.onRemoveCompleted(packageName, false);
4469                        } catch (RemoteException e) {
4470                            Slog.i(TAG, "Observer no longer exists.");
4471                        }
4472                    }
4473                    return false;
4474                }
4475                if (uid == pkgUid || checkComponentPermission(
4476                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4477                        pid, uid, -1, true)
4478                        == PackageManager.PERMISSION_GRANTED) {
4479                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4480                } else {
4481                    throw new SecurityException("PID " + pid + " does not have permission "
4482                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4483                                    + " of package " + packageName);
4484                }
4485            }
4486
4487            try {
4488                // Clear application user data
4489                pm.clearApplicationUserData(packageName, observer, userId);
4490
4491                // Remove all permissions granted from/to this package
4492                removeUriPermissionsForPackageLocked(packageName, userId, true);
4493
4494                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4495                        Uri.fromParts("package", packageName, null));
4496                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4497                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4498                        null, null, 0, null, null, null, false, false, userId);
4499            } catch (RemoteException e) {
4500            }
4501        } finally {
4502            Binder.restoreCallingIdentity(callingId);
4503        }
4504        return true;
4505    }
4506
4507    @Override
4508    public void killBackgroundProcesses(final String packageName, int userId) {
4509        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4510                != PackageManager.PERMISSION_GRANTED &&
4511                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4512                        != PackageManager.PERMISSION_GRANTED) {
4513            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4514                    + Binder.getCallingPid()
4515                    + ", uid=" + Binder.getCallingUid()
4516                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4517            Slog.w(TAG, msg);
4518            throw new SecurityException(msg);
4519        }
4520
4521        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4522                userId, true, true, "killBackgroundProcesses", null);
4523        long callingId = Binder.clearCallingIdentity();
4524        try {
4525            IPackageManager pm = AppGlobals.getPackageManager();
4526            synchronized(this) {
4527                int appId = -1;
4528                try {
4529                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4530                } catch (RemoteException e) {
4531                }
4532                if (appId == -1) {
4533                    Slog.w(TAG, "Invalid packageName: " + packageName);
4534                    return;
4535                }
4536                killPackageProcessesLocked(packageName, appId, userId,
4537                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4538            }
4539        } finally {
4540            Binder.restoreCallingIdentity(callingId);
4541        }
4542    }
4543
4544    @Override
4545    public void killAllBackgroundProcesses() {
4546        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4547                != PackageManager.PERMISSION_GRANTED) {
4548            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4549                    + Binder.getCallingPid()
4550                    + ", uid=" + Binder.getCallingUid()
4551                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4552            Slog.w(TAG, msg);
4553            throw new SecurityException(msg);
4554        }
4555
4556        long callingId = Binder.clearCallingIdentity();
4557        try {
4558            synchronized(this) {
4559                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4560                final int NP = mProcessNames.getMap().size();
4561                for (int ip=0; ip<NP; ip++) {
4562                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4563                    final int NA = apps.size();
4564                    for (int ia=0; ia<NA; ia++) {
4565                        ProcessRecord app = apps.valueAt(ia);
4566                        if (app.persistent) {
4567                            // we don't kill persistent processes
4568                            continue;
4569                        }
4570                        if (app.removed) {
4571                            procs.add(app);
4572                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4573                            app.removed = true;
4574                            procs.add(app);
4575                        }
4576                    }
4577                }
4578
4579                int N = procs.size();
4580                for (int i=0; i<N; i++) {
4581                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4582                }
4583                mAllowLowerMemLevel = true;
4584                updateOomAdjLocked();
4585                doLowMemReportIfNeededLocked(null);
4586            }
4587        } finally {
4588            Binder.restoreCallingIdentity(callingId);
4589        }
4590    }
4591
4592    @Override
4593    public void forceStopPackage(final String packageName, int userId) {
4594        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4595                != PackageManager.PERMISSION_GRANTED) {
4596            String msg = "Permission Denial: forceStopPackage() from pid="
4597                    + Binder.getCallingPid()
4598                    + ", uid=" + Binder.getCallingUid()
4599                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4600            Slog.w(TAG, msg);
4601            throw new SecurityException(msg);
4602        }
4603        final int callingPid = Binder.getCallingPid();
4604        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4605                userId, true, true, "forceStopPackage", null);
4606        long callingId = Binder.clearCallingIdentity();
4607        try {
4608            IPackageManager pm = AppGlobals.getPackageManager();
4609            synchronized(this) {
4610                int[] users = userId == UserHandle.USER_ALL
4611                        ? getUsersLocked() : new int[] { userId };
4612                for (int user : users) {
4613                    int pkgUid = -1;
4614                    try {
4615                        pkgUid = pm.getPackageUid(packageName, user);
4616                    } catch (RemoteException e) {
4617                    }
4618                    if (pkgUid == -1) {
4619                        Slog.w(TAG, "Invalid packageName: " + packageName);
4620                        continue;
4621                    }
4622                    try {
4623                        pm.setPackageStoppedState(packageName, true, user);
4624                    } catch (RemoteException e) {
4625                    } catch (IllegalArgumentException e) {
4626                        Slog.w(TAG, "Failed trying to unstop package "
4627                                + packageName + ": " + e);
4628                    }
4629                    if (isUserRunningLocked(user, false)) {
4630                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4631                    }
4632                }
4633            }
4634        } finally {
4635            Binder.restoreCallingIdentity(callingId);
4636        }
4637    }
4638
4639    /*
4640     * The pkg name and app id have to be specified.
4641     */
4642    @Override
4643    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4644        if (pkg == null) {
4645            return;
4646        }
4647        // Make sure the uid is valid.
4648        if (appid < 0) {
4649            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4650            return;
4651        }
4652        int callerUid = Binder.getCallingUid();
4653        // Only the system server can kill an application
4654        if (callerUid == Process.SYSTEM_UID) {
4655            // Post an aysnc message to kill the application
4656            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4657            msg.arg1 = appid;
4658            msg.arg2 = 0;
4659            Bundle bundle = new Bundle();
4660            bundle.putString("pkg", pkg);
4661            bundle.putString("reason", reason);
4662            msg.obj = bundle;
4663            mHandler.sendMessage(msg);
4664        } else {
4665            throw new SecurityException(callerUid + " cannot kill pkg: " +
4666                    pkg);
4667        }
4668    }
4669
4670    @Override
4671    public void closeSystemDialogs(String reason) {
4672        enforceNotIsolatedCaller("closeSystemDialogs");
4673
4674        final int pid = Binder.getCallingPid();
4675        final int uid = Binder.getCallingUid();
4676        final long origId = Binder.clearCallingIdentity();
4677        try {
4678            synchronized (this) {
4679                // Only allow this from foreground processes, so that background
4680                // applications can't abuse it to prevent system UI from being shown.
4681                if (uid >= Process.FIRST_APPLICATION_UID) {
4682                    ProcessRecord proc;
4683                    synchronized (mPidsSelfLocked) {
4684                        proc = mPidsSelfLocked.get(pid);
4685                    }
4686                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4687                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4688                                + " from background process " + proc);
4689                        return;
4690                    }
4691                }
4692                closeSystemDialogsLocked(reason);
4693            }
4694        } finally {
4695            Binder.restoreCallingIdentity(origId);
4696        }
4697    }
4698
4699    void closeSystemDialogsLocked(String reason) {
4700        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4701        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4702                | Intent.FLAG_RECEIVER_FOREGROUND);
4703        if (reason != null) {
4704            intent.putExtra("reason", reason);
4705        }
4706        mWindowManager.closeSystemDialogs(reason);
4707
4708        mStackSupervisor.closeSystemDialogsLocked();
4709
4710        broadcastIntentLocked(null, null, intent, null,
4711                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4712                Process.SYSTEM_UID, UserHandle.USER_ALL);
4713    }
4714
4715    @Override
4716    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4717        enforceNotIsolatedCaller("getProcessMemoryInfo");
4718        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4719        for (int i=pids.length-1; i>=0; i--) {
4720            ProcessRecord proc;
4721            int oomAdj;
4722            synchronized (this) {
4723                synchronized (mPidsSelfLocked) {
4724                    proc = mPidsSelfLocked.get(pids[i]);
4725                    oomAdj = proc != null ? proc.setAdj : 0;
4726                }
4727            }
4728            infos[i] = new Debug.MemoryInfo();
4729            Debug.getMemoryInfo(pids[i], infos[i]);
4730            if (proc != null) {
4731                synchronized (this) {
4732                    if (proc.thread != null && proc.setAdj == oomAdj) {
4733                        // Record this for posterity if the process has been stable.
4734                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4735                                infos[i].getTotalUss(), false, proc.pkgList);
4736                    }
4737                }
4738            }
4739        }
4740        return infos;
4741    }
4742
4743    @Override
4744    public long[] getProcessPss(int[] pids) {
4745        enforceNotIsolatedCaller("getProcessPss");
4746        long[] pss = new long[pids.length];
4747        for (int i=pids.length-1; i>=0; i--) {
4748            ProcessRecord proc;
4749            int oomAdj;
4750            synchronized (this) {
4751                synchronized (mPidsSelfLocked) {
4752                    proc = mPidsSelfLocked.get(pids[i]);
4753                    oomAdj = proc != null ? proc.setAdj : 0;
4754                }
4755            }
4756            long[] tmpUss = new long[1];
4757            pss[i] = Debug.getPss(pids[i], tmpUss);
4758            if (proc != null) {
4759                synchronized (this) {
4760                    if (proc.thread != null && proc.setAdj == oomAdj) {
4761                        // Record this for posterity if the process has been stable.
4762                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4763                    }
4764                }
4765            }
4766        }
4767        return pss;
4768    }
4769
4770    @Override
4771    public void killApplicationProcess(String processName, int uid) {
4772        if (processName == null) {
4773            return;
4774        }
4775
4776        int callerUid = Binder.getCallingUid();
4777        // Only the system server can kill an application
4778        if (callerUid == Process.SYSTEM_UID) {
4779            synchronized (this) {
4780                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4781                if (app != null && app.thread != null) {
4782                    try {
4783                        app.thread.scheduleSuicide();
4784                    } catch (RemoteException e) {
4785                        // If the other end already died, then our work here is done.
4786                    }
4787                } else {
4788                    Slog.w(TAG, "Process/uid not found attempting kill of "
4789                            + processName + " / " + uid);
4790                }
4791            }
4792        } else {
4793            throw new SecurityException(callerUid + " cannot kill app process: " +
4794                    processName);
4795        }
4796    }
4797
4798    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4799        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4800                false, true, false, false, UserHandle.getUserId(uid), reason);
4801        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4802                Uri.fromParts("package", packageName, null));
4803        if (!mProcessesReady) {
4804            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4805                    | Intent.FLAG_RECEIVER_FOREGROUND);
4806        }
4807        intent.putExtra(Intent.EXTRA_UID, uid);
4808        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4809        broadcastIntentLocked(null, null, intent,
4810                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4811                false, false,
4812                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4813    }
4814
4815    private void forceStopUserLocked(int userId, String reason) {
4816        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4817        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4818        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4819                | Intent.FLAG_RECEIVER_FOREGROUND);
4820        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4821        broadcastIntentLocked(null, null, intent,
4822                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4823                false, false,
4824                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4825    }
4826
4827    private final boolean killPackageProcessesLocked(String packageName, int appId,
4828            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4829            boolean doit, boolean evenPersistent, String reason) {
4830        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4831
4832        // Remove all processes this package may have touched: all with the
4833        // same UID (except for the system or root user), and all whose name
4834        // matches the package name.
4835        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4836        final int NP = mProcessNames.getMap().size();
4837        for (int ip=0; ip<NP; ip++) {
4838            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4839            final int NA = apps.size();
4840            for (int ia=0; ia<NA; ia++) {
4841                ProcessRecord app = apps.valueAt(ia);
4842                if (app.persistent && !evenPersistent) {
4843                    // we don't kill persistent processes
4844                    continue;
4845                }
4846                if (app.removed) {
4847                    if (doit) {
4848                        procs.add(app);
4849                    }
4850                    continue;
4851                }
4852
4853                // Skip process if it doesn't meet our oom adj requirement.
4854                if (app.setAdj < minOomAdj) {
4855                    continue;
4856                }
4857
4858                // If no package is specified, we call all processes under the
4859                // give user id.
4860                if (packageName == null) {
4861                    if (app.userId != userId) {
4862                        continue;
4863                    }
4864                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4865                        continue;
4866                    }
4867                // Package has been specified, we want to hit all processes
4868                // that match it.  We need to qualify this by the processes
4869                // that are running under the specified app and user ID.
4870                } else {
4871                    if (UserHandle.getAppId(app.uid) != appId) {
4872                        continue;
4873                    }
4874                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4875                        continue;
4876                    }
4877                    if (!app.pkgList.containsKey(packageName)) {
4878                        continue;
4879                    }
4880                }
4881
4882                // Process has passed all conditions, kill it!
4883                if (!doit) {
4884                    return true;
4885                }
4886                app.removed = true;
4887                procs.add(app);
4888            }
4889        }
4890
4891        int N = procs.size();
4892        for (int i=0; i<N; i++) {
4893            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4894        }
4895        updateOomAdjLocked();
4896        return N > 0;
4897    }
4898
4899    private final boolean forceStopPackageLocked(String name, int appId,
4900            boolean callerWillRestart, boolean purgeCache, boolean doit,
4901            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4902        int i;
4903        int N;
4904
4905        if (userId == UserHandle.USER_ALL && name == null) {
4906            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4907        }
4908
4909        if (appId < 0 && name != null) {
4910            try {
4911                appId = UserHandle.getAppId(
4912                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4913            } catch (RemoteException e) {
4914            }
4915        }
4916
4917        if (doit) {
4918            if (name != null) {
4919                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4920                        + " user=" + userId + ": " + reason);
4921            } else {
4922                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4923            }
4924
4925            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4926            for (int ip=pmap.size()-1; ip>=0; ip--) {
4927                SparseArray<Long> ba = pmap.valueAt(ip);
4928                for (i=ba.size()-1; i>=0; i--) {
4929                    boolean remove = false;
4930                    final int entUid = ba.keyAt(i);
4931                    if (name != null) {
4932                        if (userId == UserHandle.USER_ALL) {
4933                            if (UserHandle.getAppId(entUid) == appId) {
4934                                remove = true;
4935                            }
4936                        } else {
4937                            if (entUid == UserHandle.getUid(userId, appId)) {
4938                                remove = true;
4939                            }
4940                        }
4941                    } else if (UserHandle.getUserId(entUid) == userId) {
4942                        remove = true;
4943                    }
4944                    if (remove) {
4945                        ba.removeAt(i);
4946                    }
4947                }
4948                if (ba.size() == 0) {
4949                    pmap.removeAt(ip);
4950                }
4951            }
4952        }
4953
4954        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4955                -100, callerWillRestart, true, doit, evenPersistent,
4956                name == null ? ("stop user " + userId) : ("stop " + name));
4957
4958        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4959            if (!doit) {
4960                return true;
4961            }
4962            didSomething = true;
4963        }
4964
4965        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4966            if (!doit) {
4967                return true;
4968            }
4969            didSomething = true;
4970        }
4971
4972        if (name == null) {
4973            // Remove all sticky broadcasts from this user.
4974            mStickyBroadcasts.remove(userId);
4975        }
4976
4977        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4978        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4979                userId, providers)) {
4980            if (!doit) {
4981                return true;
4982            }
4983            didSomething = true;
4984        }
4985        N = providers.size();
4986        for (i=0; i<N; i++) {
4987            removeDyingProviderLocked(null, providers.get(i), true);
4988        }
4989
4990        // Remove transient permissions granted from/to this package/user
4991        removeUriPermissionsForPackageLocked(name, userId, false);
4992
4993        if (name == null || uninstalling) {
4994            // Remove pending intents.  For now we only do this when force
4995            // stopping users, because we have some problems when doing this
4996            // for packages -- app widgets are not currently cleaned up for
4997            // such packages, so they can be left with bad pending intents.
4998            if (mIntentSenderRecords.size() > 0) {
4999                Iterator<WeakReference<PendingIntentRecord>> it
5000                        = mIntentSenderRecords.values().iterator();
5001                while (it.hasNext()) {
5002                    WeakReference<PendingIntentRecord> wpir = it.next();
5003                    if (wpir == null) {
5004                        it.remove();
5005                        continue;
5006                    }
5007                    PendingIntentRecord pir = wpir.get();
5008                    if (pir == null) {
5009                        it.remove();
5010                        continue;
5011                    }
5012                    if (name == null) {
5013                        // Stopping user, remove all objects for the user.
5014                        if (pir.key.userId != userId) {
5015                            // Not the same user, skip it.
5016                            continue;
5017                        }
5018                    } else {
5019                        if (UserHandle.getAppId(pir.uid) != appId) {
5020                            // Different app id, skip it.
5021                            continue;
5022                        }
5023                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5024                            // Different user, skip it.
5025                            continue;
5026                        }
5027                        if (!pir.key.packageName.equals(name)) {
5028                            // Different package, skip it.
5029                            continue;
5030                        }
5031                    }
5032                    if (!doit) {
5033                        return true;
5034                    }
5035                    didSomething = true;
5036                    it.remove();
5037                    pir.canceled = true;
5038                    if (pir.key.activity != null) {
5039                        pir.key.activity.pendingResults.remove(pir.ref);
5040                    }
5041                }
5042            }
5043        }
5044
5045        if (doit) {
5046            if (purgeCache && name != null) {
5047                AttributeCache ac = AttributeCache.instance();
5048                if (ac != null) {
5049                    ac.removePackage(name);
5050                }
5051            }
5052            if (mBooted) {
5053                mStackSupervisor.resumeTopActivitiesLocked();
5054                mStackSupervisor.scheduleIdleLocked();
5055            }
5056        }
5057
5058        return didSomething;
5059    }
5060
5061    private final boolean removeProcessLocked(ProcessRecord app,
5062            boolean callerWillRestart, boolean allowRestart, String reason) {
5063        final String name = app.processName;
5064        final int uid = app.uid;
5065        if (DEBUG_PROCESSES) Slog.d(
5066            TAG, "Force removing proc " + app.toShortString() + " (" + name
5067            + "/" + uid + ")");
5068
5069        mProcessNames.remove(name, uid);
5070        mIsolatedProcesses.remove(app.uid);
5071        if (mHeavyWeightProcess == app) {
5072            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5073                    mHeavyWeightProcess.userId, 0));
5074            mHeavyWeightProcess = null;
5075        }
5076        boolean needRestart = false;
5077        if (app.pid > 0 && app.pid != MY_PID) {
5078            int pid = app.pid;
5079            synchronized (mPidsSelfLocked) {
5080                mPidsSelfLocked.remove(pid);
5081                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5082            }
5083            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5084                    app.processName, app.info.uid);
5085            if (app.isolated) {
5086                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5087            }
5088            killUnneededProcessLocked(app, reason);
5089            handleAppDiedLocked(app, true, allowRestart);
5090            removeLruProcessLocked(app);
5091
5092            if (app.persistent && !app.isolated) {
5093                if (!callerWillRestart) {
5094                    addAppLocked(app.info, false, null /* ABI override */);
5095                } else {
5096                    needRestart = true;
5097                }
5098            }
5099        } else {
5100            mRemovedProcesses.add(app);
5101        }
5102
5103        return needRestart;
5104    }
5105
5106    private final void processStartTimedOutLocked(ProcessRecord app) {
5107        final int pid = app.pid;
5108        boolean gone = false;
5109        synchronized (mPidsSelfLocked) {
5110            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5111            if (knownApp != null && knownApp.thread == null) {
5112                mPidsSelfLocked.remove(pid);
5113                gone = true;
5114            }
5115        }
5116
5117        if (gone) {
5118            Slog.w(TAG, "Process " + app + " failed to attach");
5119            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5120                    pid, app.uid, app.processName);
5121            mProcessNames.remove(app.processName, app.uid);
5122            mIsolatedProcesses.remove(app.uid);
5123            if (mHeavyWeightProcess == app) {
5124                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5125                        mHeavyWeightProcess.userId, 0));
5126                mHeavyWeightProcess = null;
5127            }
5128            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5129                    app.processName, app.info.uid);
5130            if (app.isolated) {
5131                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5132            }
5133            // Take care of any launching providers waiting for this process.
5134            checkAppInLaunchingProvidersLocked(app, true);
5135            // Take care of any services that are waiting for the process.
5136            mServices.processStartTimedOutLocked(app);
5137            killUnneededProcessLocked(app, "start timeout");
5138            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5139                Slog.w(TAG, "Unattached app died before backup, skipping");
5140                try {
5141                    IBackupManager bm = IBackupManager.Stub.asInterface(
5142                            ServiceManager.getService(Context.BACKUP_SERVICE));
5143                    bm.agentDisconnected(app.info.packageName);
5144                } catch (RemoteException e) {
5145                    // Can't happen; the backup manager is local
5146                }
5147            }
5148            if (isPendingBroadcastProcessLocked(pid)) {
5149                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5150                skipPendingBroadcastLocked(pid);
5151            }
5152        } else {
5153            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5154        }
5155    }
5156
5157    private final boolean attachApplicationLocked(IApplicationThread thread,
5158            int pid) {
5159
5160        // Find the application record that is being attached...  either via
5161        // the pid if we are running in multiple processes, or just pull the
5162        // next app record if we are emulating process with anonymous threads.
5163        ProcessRecord app;
5164        if (pid != MY_PID && pid >= 0) {
5165            synchronized (mPidsSelfLocked) {
5166                app = mPidsSelfLocked.get(pid);
5167            }
5168        } else {
5169            app = null;
5170        }
5171
5172        if (app == null) {
5173            Slog.w(TAG, "No pending application record for pid " + pid
5174                    + " (IApplicationThread " + thread + "); dropping process");
5175            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5176            if (pid > 0 && pid != MY_PID) {
5177                Process.killProcessQuiet(pid);
5178            } else {
5179                try {
5180                    thread.scheduleExit();
5181                } catch (Exception e) {
5182                    // Ignore exceptions.
5183                }
5184            }
5185            return false;
5186        }
5187
5188        // If this application record is still attached to a previous
5189        // process, clean it up now.
5190        if (app.thread != null) {
5191            handleAppDiedLocked(app, true, true);
5192        }
5193
5194        // Tell the process all about itself.
5195
5196        if (localLOGV) Slog.v(
5197                TAG, "Binding process pid " + pid + " to record " + app);
5198
5199        final String processName = app.processName;
5200        try {
5201            AppDeathRecipient adr = new AppDeathRecipient(
5202                    app, pid, thread);
5203            thread.asBinder().linkToDeath(adr, 0);
5204            app.deathRecipient = adr;
5205        } catch (RemoteException e) {
5206            app.resetPackageList(mProcessStats);
5207            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5208            return false;
5209        }
5210
5211        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5212
5213        app.makeActive(thread, mProcessStats);
5214        app.curAdj = app.setAdj = -100;
5215        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5216        app.forcingToForeground = null;
5217        updateProcessForegroundLocked(app, false, false);
5218        app.hasShownUi = false;
5219        app.debugging = false;
5220        app.cached = false;
5221
5222        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5223
5224        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5225        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5226
5227        if (!normalMode) {
5228            Slog.i(TAG, "Launching preboot mode app: " + app);
5229        }
5230
5231        if (localLOGV) Slog.v(
5232            TAG, "New app record " + app
5233            + " thread=" + thread.asBinder() + " pid=" + pid);
5234        try {
5235            int testMode = IApplicationThread.DEBUG_OFF;
5236            if (mDebugApp != null && mDebugApp.equals(processName)) {
5237                testMode = mWaitForDebugger
5238                    ? IApplicationThread.DEBUG_WAIT
5239                    : IApplicationThread.DEBUG_ON;
5240                app.debugging = true;
5241                if (mDebugTransient) {
5242                    mDebugApp = mOrigDebugApp;
5243                    mWaitForDebugger = mOrigWaitForDebugger;
5244                }
5245            }
5246            String profileFile = app.instrumentationProfileFile;
5247            ParcelFileDescriptor profileFd = null;
5248            boolean profileAutoStop = false;
5249            if (mProfileApp != null && mProfileApp.equals(processName)) {
5250                mProfileProc = app;
5251                profileFile = mProfileFile;
5252                profileFd = mProfileFd;
5253                profileAutoStop = mAutoStopProfiler;
5254            }
5255            boolean enableOpenGlTrace = false;
5256            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5257                enableOpenGlTrace = true;
5258                mOpenGlTraceApp = null;
5259            }
5260
5261            // If the app is being launched for restore or full backup, set it up specially
5262            boolean isRestrictedBackupMode = false;
5263            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5264                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5265                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5266                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5267            }
5268
5269            ensurePackageDexOpt(app.instrumentationInfo != null
5270                    ? app.instrumentationInfo.packageName
5271                    : app.info.packageName);
5272            if (app.instrumentationClass != null) {
5273                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5274            }
5275            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5276                    + processName + " with config " + mConfiguration);
5277            ApplicationInfo appInfo = app.instrumentationInfo != null
5278                    ? app.instrumentationInfo : app.info;
5279            app.compat = compatibilityInfoForPackageLocked(appInfo);
5280            if (profileFd != null) {
5281                profileFd = profileFd.dup();
5282            }
5283            thread.bindApplication(processName, appInfo, providers,
5284                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5285                    app.instrumentationArguments, app.instrumentationWatcher,
5286                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5287                    isRestrictedBackupMode || !normalMode, app.persistent,
5288                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5289                    mCoreSettingsObserver.getCoreSettingsLocked());
5290            updateLruProcessLocked(app, false, null);
5291            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5292        } catch (Exception e) {
5293            // todo: Yikes!  What should we do?  For now we will try to
5294            // start another process, but that could easily get us in
5295            // an infinite loop of restarting processes...
5296            Slog.w(TAG, "Exception thrown during bind!", e);
5297
5298            app.resetPackageList(mProcessStats);
5299            app.unlinkDeathRecipient();
5300            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5301            return false;
5302        }
5303
5304        // Remove this record from the list of starting applications.
5305        mPersistentStartingProcesses.remove(app);
5306        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5307                "Attach application locked removing on hold: " + app);
5308        mProcessesOnHold.remove(app);
5309
5310        boolean badApp = false;
5311        boolean didSomething = false;
5312
5313        // See if the top visible activity is waiting to run in this process...
5314        if (normalMode) {
5315            try {
5316                if (mStackSupervisor.attachApplicationLocked(app)) {
5317                    didSomething = true;
5318                }
5319            } catch (Exception e) {
5320                badApp = true;
5321            }
5322        }
5323
5324        // Find any services that should be running in this process...
5325        if (!badApp) {
5326            try {
5327                didSomething |= mServices.attachApplicationLocked(app, processName);
5328            } catch (Exception e) {
5329                badApp = true;
5330            }
5331        }
5332
5333        // Check if a next-broadcast receiver is in this process...
5334        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5335            try {
5336                didSomething |= sendPendingBroadcastsLocked(app);
5337            } catch (Exception e) {
5338                // If the app died trying to launch the receiver we declare it 'bad'
5339                badApp = true;
5340            }
5341        }
5342
5343        // Check whether the next backup agent is in this process...
5344        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5345            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5346            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5347            try {
5348                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5349                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5350                        mBackupTarget.backupMode);
5351            } catch (Exception e) {
5352                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5353                e.printStackTrace();
5354            }
5355        }
5356
5357        if (badApp) {
5358            // todo: Also need to kill application to deal with all
5359            // kinds of exceptions.
5360            handleAppDiedLocked(app, false, true);
5361            return false;
5362        }
5363
5364        if (!didSomething) {
5365            updateOomAdjLocked();
5366        }
5367
5368        return true;
5369    }
5370
5371    @Override
5372    public final void attachApplication(IApplicationThread thread) {
5373        synchronized (this) {
5374            int callingPid = Binder.getCallingPid();
5375            final long origId = Binder.clearCallingIdentity();
5376            attachApplicationLocked(thread, callingPid);
5377            Binder.restoreCallingIdentity(origId);
5378        }
5379    }
5380
5381    @Override
5382    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5383        final long origId = Binder.clearCallingIdentity();
5384        synchronized (this) {
5385            ActivityStack stack = ActivityRecord.getStackLocked(token);
5386            if (stack != null) {
5387                ActivityRecord r =
5388                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5389                if (stopProfiling) {
5390                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5391                        try {
5392                            mProfileFd.close();
5393                        } catch (IOException e) {
5394                        }
5395                        clearProfilerLocked();
5396                    }
5397                }
5398            }
5399        }
5400        Binder.restoreCallingIdentity(origId);
5401    }
5402
5403    void enableScreenAfterBoot() {
5404        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5405                SystemClock.uptimeMillis());
5406        mWindowManager.enableScreenAfterBoot();
5407
5408        synchronized (this) {
5409            updateEventDispatchingLocked();
5410        }
5411    }
5412
5413    @Override
5414    public void showBootMessage(final CharSequence msg, final boolean always) {
5415        enforceNotIsolatedCaller("showBootMessage");
5416        mWindowManager.showBootMessage(msg, always);
5417    }
5418
5419    @Override
5420    public void dismissKeyguardOnNextActivity() {
5421        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5422        final long token = Binder.clearCallingIdentity();
5423        try {
5424            synchronized (this) {
5425                if (DEBUG_LOCKSCREEN) logLockScreen("");
5426                if (mLockScreenShown) {
5427                    mLockScreenShown = false;
5428                    comeOutOfSleepIfNeededLocked();
5429                }
5430                mStackSupervisor.setDismissKeyguard(true);
5431            }
5432        } finally {
5433            Binder.restoreCallingIdentity(token);
5434        }
5435    }
5436
5437    final void finishBooting() {
5438        // Register receivers to handle package update events
5439        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5440
5441        synchronized (this) {
5442            // Ensure that any processes we had put on hold are now started
5443            // up.
5444            final int NP = mProcessesOnHold.size();
5445            if (NP > 0) {
5446                ArrayList<ProcessRecord> procs =
5447                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5448                for (int ip=0; ip<NP; ip++) {
5449                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5450                            + procs.get(ip));
5451                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5452                }
5453            }
5454
5455            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5456                // Start looking for apps that are abusing wake locks.
5457                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5458                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5459                // Tell anyone interested that we are done booting!
5460                SystemProperties.set("sys.boot_completed", "1");
5461                SystemProperties.set("dev.bootcomplete", "1");
5462                for (int i=0; i<mStartedUsers.size(); i++) {
5463                    UserStartedState uss = mStartedUsers.valueAt(i);
5464                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5465                        uss.mState = UserStartedState.STATE_RUNNING;
5466                        final int userId = mStartedUsers.keyAt(i);
5467                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5468                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5469                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5470                        broadcastIntentLocked(null, null, intent, null,
5471                                new IIntentReceiver.Stub() {
5472                                    @Override
5473                                    public void performReceive(Intent intent, int resultCode,
5474                                            String data, Bundle extras, boolean ordered,
5475                                            boolean sticky, int sendingUser) {
5476                                        synchronized (ActivityManagerService.this) {
5477                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5478                                                    true, false);
5479                                        }
5480                                    }
5481                                },
5482                                0, null, null,
5483                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5484                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5485                                userId);
5486                    }
5487                }
5488                scheduleStartProfilesLocked();
5489            }
5490        }
5491    }
5492
5493    final void ensureBootCompleted() {
5494        boolean booting;
5495        boolean enableScreen;
5496        synchronized (this) {
5497            booting = mBooting;
5498            mBooting = false;
5499            enableScreen = !mBooted;
5500            mBooted = true;
5501        }
5502
5503        if (booting) {
5504            finishBooting();
5505        }
5506
5507        if (enableScreen) {
5508            enableScreenAfterBoot();
5509        }
5510    }
5511
5512    @Override
5513    public final void activityResumed(IBinder token) {
5514        final long origId = Binder.clearCallingIdentity();
5515        synchronized(this) {
5516            ActivityStack stack = ActivityRecord.getStackLocked(token);
5517            if (stack != null) {
5518                ActivityRecord.activityResumedLocked(token);
5519            }
5520        }
5521        Binder.restoreCallingIdentity(origId);
5522    }
5523
5524    @Override
5525    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5526        final long origId = Binder.clearCallingIdentity();
5527        synchronized(this) {
5528            ActivityStack stack = ActivityRecord.getStackLocked(token);
5529            if (stack != null) {
5530                stack.activityPausedLocked(token, false, persistentState);
5531            }
5532        }
5533        Binder.restoreCallingIdentity(origId);
5534    }
5535
5536    @Override
5537    public final void activityStopped(IBinder token, Bundle icicle,
5538            PersistableBundle persistentState, CharSequence description) {
5539        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5540
5541        // Refuse possible leaked file descriptors
5542        if (icicle != null && icicle.hasFileDescriptors()) {
5543            throw new IllegalArgumentException("File descriptors passed in Bundle");
5544        }
5545
5546        final long origId = Binder.clearCallingIdentity();
5547
5548        synchronized (this) {
5549            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5550            if (r != null) {
5551                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5552            }
5553        }
5554
5555        trimApplications();
5556
5557        Binder.restoreCallingIdentity(origId);
5558    }
5559
5560    @Override
5561    public final void activityDestroyed(IBinder token) {
5562        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5563        synchronized (this) {
5564            ActivityStack stack = ActivityRecord.getStackLocked(token);
5565            if (stack != null) {
5566                stack.activityDestroyedLocked(token);
5567            }
5568        }
5569    }
5570
5571    @Override
5572    public String getCallingPackage(IBinder token) {
5573        synchronized (this) {
5574            ActivityRecord r = getCallingRecordLocked(token);
5575            return r != null ? r.info.packageName : null;
5576        }
5577    }
5578
5579    @Override
5580    public ComponentName getCallingActivity(IBinder token) {
5581        synchronized (this) {
5582            ActivityRecord r = getCallingRecordLocked(token);
5583            return r != null ? r.intent.getComponent() : null;
5584        }
5585    }
5586
5587    private ActivityRecord getCallingRecordLocked(IBinder token) {
5588        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5589        if (r == null) {
5590            return null;
5591        }
5592        return r.resultTo;
5593    }
5594
5595    @Override
5596    public ComponentName getActivityClassForToken(IBinder token) {
5597        synchronized(this) {
5598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5599            if (r == null) {
5600                return null;
5601            }
5602            return r.intent.getComponent();
5603        }
5604    }
5605
5606    @Override
5607    public String getPackageForToken(IBinder token) {
5608        synchronized(this) {
5609            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5610            if (r == null) {
5611                return null;
5612            }
5613            return r.packageName;
5614        }
5615    }
5616
5617    @Override
5618    public IIntentSender getIntentSender(int type,
5619            String packageName, IBinder token, String resultWho,
5620            int requestCode, Intent[] intents, String[] resolvedTypes,
5621            int flags, Bundle options, int userId) {
5622        enforceNotIsolatedCaller("getIntentSender");
5623        // Refuse possible leaked file descriptors
5624        if (intents != null) {
5625            if (intents.length < 1) {
5626                throw new IllegalArgumentException("Intents array length must be >= 1");
5627            }
5628            for (int i=0; i<intents.length; i++) {
5629                Intent intent = intents[i];
5630                if (intent != null) {
5631                    if (intent.hasFileDescriptors()) {
5632                        throw new IllegalArgumentException("File descriptors passed in Intent");
5633                    }
5634                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5635                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5636                        throw new IllegalArgumentException(
5637                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5638                    }
5639                    intents[i] = new Intent(intent);
5640                }
5641            }
5642            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5643                throw new IllegalArgumentException(
5644                        "Intent array length does not match resolvedTypes length");
5645            }
5646        }
5647        if (options != null) {
5648            if (options.hasFileDescriptors()) {
5649                throw new IllegalArgumentException("File descriptors passed in options");
5650            }
5651        }
5652
5653        synchronized(this) {
5654            int callingUid = Binder.getCallingUid();
5655            int origUserId = userId;
5656            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5657                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5658                    "getIntentSender", null);
5659            if (origUserId == UserHandle.USER_CURRENT) {
5660                // We don't want to evaluate this until the pending intent is
5661                // actually executed.  However, we do want to always do the
5662                // security checking for it above.
5663                userId = UserHandle.USER_CURRENT;
5664            }
5665            try {
5666                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5667                    int uid = AppGlobals.getPackageManager()
5668                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5669                    if (!UserHandle.isSameApp(callingUid, uid)) {
5670                        String msg = "Permission Denial: getIntentSender() from pid="
5671                            + Binder.getCallingPid()
5672                            + ", uid=" + Binder.getCallingUid()
5673                            + ", (need uid=" + uid + ")"
5674                            + " is not allowed to send as package " + packageName;
5675                        Slog.w(TAG, msg);
5676                        throw new SecurityException(msg);
5677                    }
5678                }
5679
5680                return getIntentSenderLocked(type, packageName, callingUid, userId,
5681                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5682
5683            } catch (RemoteException e) {
5684                throw new SecurityException(e);
5685            }
5686        }
5687    }
5688
5689    IIntentSender getIntentSenderLocked(int type, String packageName,
5690            int callingUid, int userId, IBinder token, String resultWho,
5691            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5692            Bundle options) {
5693        if (DEBUG_MU)
5694            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5695        ActivityRecord activity = null;
5696        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5697            activity = ActivityRecord.isInStackLocked(token);
5698            if (activity == null) {
5699                return null;
5700            }
5701            if (activity.finishing) {
5702                return null;
5703            }
5704        }
5705
5706        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5707        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5708        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5709        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5710                |PendingIntent.FLAG_UPDATE_CURRENT);
5711
5712        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5713                type, packageName, activity, resultWho,
5714                requestCode, intents, resolvedTypes, flags, options, userId);
5715        WeakReference<PendingIntentRecord> ref;
5716        ref = mIntentSenderRecords.get(key);
5717        PendingIntentRecord rec = ref != null ? ref.get() : null;
5718        if (rec != null) {
5719            if (!cancelCurrent) {
5720                if (updateCurrent) {
5721                    if (rec.key.requestIntent != null) {
5722                        rec.key.requestIntent.replaceExtras(intents != null ?
5723                                intents[intents.length - 1] : null);
5724                    }
5725                    if (intents != null) {
5726                        intents[intents.length-1] = rec.key.requestIntent;
5727                        rec.key.allIntents = intents;
5728                        rec.key.allResolvedTypes = resolvedTypes;
5729                    } else {
5730                        rec.key.allIntents = null;
5731                        rec.key.allResolvedTypes = null;
5732                    }
5733                }
5734                return rec;
5735            }
5736            rec.canceled = true;
5737            mIntentSenderRecords.remove(key);
5738        }
5739        if (noCreate) {
5740            return rec;
5741        }
5742        rec = new PendingIntentRecord(this, key, callingUid);
5743        mIntentSenderRecords.put(key, rec.ref);
5744        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5745            if (activity.pendingResults == null) {
5746                activity.pendingResults
5747                        = new HashSet<WeakReference<PendingIntentRecord>>();
5748            }
5749            activity.pendingResults.add(rec.ref);
5750        }
5751        return rec;
5752    }
5753
5754    @Override
5755    public void cancelIntentSender(IIntentSender sender) {
5756        if (!(sender instanceof PendingIntentRecord)) {
5757            return;
5758        }
5759        synchronized(this) {
5760            PendingIntentRecord rec = (PendingIntentRecord)sender;
5761            try {
5762                int uid = AppGlobals.getPackageManager()
5763                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5764                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5765                    String msg = "Permission Denial: cancelIntentSender() from pid="
5766                        + Binder.getCallingPid()
5767                        + ", uid=" + Binder.getCallingUid()
5768                        + " is not allowed to cancel packges "
5769                        + rec.key.packageName;
5770                    Slog.w(TAG, msg);
5771                    throw new SecurityException(msg);
5772                }
5773            } catch (RemoteException e) {
5774                throw new SecurityException(e);
5775            }
5776            cancelIntentSenderLocked(rec, true);
5777        }
5778    }
5779
5780    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5781        rec.canceled = true;
5782        mIntentSenderRecords.remove(rec.key);
5783        if (cleanActivity && rec.key.activity != null) {
5784            rec.key.activity.pendingResults.remove(rec.ref);
5785        }
5786    }
5787
5788    @Override
5789    public String getPackageForIntentSender(IIntentSender pendingResult) {
5790        if (!(pendingResult instanceof PendingIntentRecord)) {
5791            return null;
5792        }
5793        try {
5794            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5795            return res.key.packageName;
5796        } catch (ClassCastException e) {
5797        }
5798        return null;
5799    }
5800
5801    @Override
5802    public int getUidForIntentSender(IIntentSender sender) {
5803        if (sender instanceof PendingIntentRecord) {
5804            try {
5805                PendingIntentRecord res = (PendingIntentRecord)sender;
5806                return res.uid;
5807            } catch (ClassCastException e) {
5808            }
5809        }
5810        return -1;
5811    }
5812
5813    @Override
5814    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5815        if (!(pendingResult instanceof PendingIntentRecord)) {
5816            return false;
5817        }
5818        try {
5819            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5820            if (res.key.allIntents == null) {
5821                return false;
5822            }
5823            for (int i=0; i<res.key.allIntents.length; i++) {
5824                Intent intent = res.key.allIntents[i];
5825                if (intent.getPackage() != null && intent.getComponent() != null) {
5826                    return false;
5827                }
5828            }
5829            return true;
5830        } catch (ClassCastException e) {
5831        }
5832        return false;
5833    }
5834
5835    @Override
5836    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5837        if (!(pendingResult instanceof PendingIntentRecord)) {
5838            return false;
5839        }
5840        try {
5841            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5842            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5843                return true;
5844            }
5845            return false;
5846        } catch (ClassCastException e) {
5847        }
5848        return false;
5849    }
5850
5851    @Override
5852    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5853        if (!(pendingResult instanceof PendingIntentRecord)) {
5854            return null;
5855        }
5856        try {
5857            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5858            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5859        } catch (ClassCastException e) {
5860        }
5861        return null;
5862    }
5863
5864    @Override
5865    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5866        if (!(pendingResult instanceof PendingIntentRecord)) {
5867            return null;
5868        }
5869        try {
5870            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5871            Intent intent = res.key.requestIntent;
5872            if (intent != null) {
5873                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5874                        || res.lastTagPrefix.equals(prefix))) {
5875                    return res.lastTag;
5876                }
5877                res.lastTagPrefix = prefix;
5878                StringBuilder sb = new StringBuilder(128);
5879                if (prefix != null) {
5880                    sb.append(prefix);
5881                }
5882                if (intent.getAction() != null) {
5883                    sb.append(intent.getAction());
5884                } else if (intent.getComponent() != null) {
5885                    intent.getComponent().appendShortString(sb);
5886                } else {
5887                    sb.append("?");
5888                }
5889                return res.lastTag = sb.toString();
5890            }
5891        } catch (ClassCastException e) {
5892        }
5893        return null;
5894    }
5895
5896    @Override
5897    public void setProcessLimit(int max) {
5898        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5899                "setProcessLimit()");
5900        synchronized (this) {
5901            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5902            mProcessLimitOverride = max;
5903        }
5904        trimApplications();
5905    }
5906
5907    @Override
5908    public int getProcessLimit() {
5909        synchronized (this) {
5910            return mProcessLimitOverride;
5911        }
5912    }
5913
5914    void foregroundTokenDied(ForegroundToken token) {
5915        synchronized (ActivityManagerService.this) {
5916            synchronized (mPidsSelfLocked) {
5917                ForegroundToken cur
5918                    = mForegroundProcesses.get(token.pid);
5919                if (cur != token) {
5920                    return;
5921                }
5922                mForegroundProcesses.remove(token.pid);
5923                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5924                if (pr == null) {
5925                    return;
5926                }
5927                pr.forcingToForeground = null;
5928                updateProcessForegroundLocked(pr, false, false);
5929            }
5930            updateOomAdjLocked();
5931        }
5932    }
5933
5934    @Override
5935    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5936        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5937                "setProcessForeground()");
5938        synchronized(this) {
5939            boolean changed = false;
5940
5941            synchronized (mPidsSelfLocked) {
5942                ProcessRecord pr = mPidsSelfLocked.get(pid);
5943                if (pr == null && isForeground) {
5944                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5945                    return;
5946                }
5947                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5948                if (oldToken != null) {
5949                    oldToken.token.unlinkToDeath(oldToken, 0);
5950                    mForegroundProcesses.remove(pid);
5951                    if (pr != null) {
5952                        pr.forcingToForeground = null;
5953                    }
5954                    changed = true;
5955                }
5956                if (isForeground && token != null) {
5957                    ForegroundToken newToken = new ForegroundToken() {
5958                        @Override
5959                        public void binderDied() {
5960                            foregroundTokenDied(this);
5961                        }
5962                    };
5963                    newToken.pid = pid;
5964                    newToken.token = token;
5965                    try {
5966                        token.linkToDeath(newToken, 0);
5967                        mForegroundProcesses.put(pid, newToken);
5968                        pr.forcingToForeground = token;
5969                        changed = true;
5970                    } catch (RemoteException e) {
5971                        // If the process died while doing this, we will later
5972                        // do the cleanup with the process death link.
5973                    }
5974                }
5975            }
5976
5977            if (changed) {
5978                updateOomAdjLocked();
5979            }
5980        }
5981    }
5982
5983    // =========================================================
5984    // PERMISSIONS
5985    // =========================================================
5986
5987    static class PermissionController extends IPermissionController.Stub {
5988        ActivityManagerService mActivityManagerService;
5989        PermissionController(ActivityManagerService activityManagerService) {
5990            mActivityManagerService = activityManagerService;
5991        }
5992
5993        @Override
5994        public boolean checkPermission(String permission, int pid, int uid) {
5995            return mActivityManagerService.checkPermission(permission, pid,
5996                    uid) == PackageManager.PERMISSION_GRANTED;
5997        }
5998    }
5999
6000    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6001        @Override
6002        public int checkComponentPermission(String permission, int pid, int uid,
6003                int owningUid, boolean exported) {
6004            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6005                    owningUid, exported);
6006        }
6007
6008        @Override
6009        public Object getAMSLock() {
6010            return ActivityManagerService.this;
6011        }
6012    }
6013
6014    /**
6015     * This can be called with or without the global lock held.
6016     */
6017    int checkComponentPermission(String permission, int pid, int uid,
6018            int owningUid, boolean exported) {
6019        // We might be performing an operation on behalf of an indirect binder
6020        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6021        // client identity accordingly before proceeding.
6022        Identity tlsIdentity = sCallerIdentity.get();
6023        if (tlsIdentity != null) {
6024            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6025                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6026            uid = tlsIdentity.uid;
6027            pid = tlsIdentity.pid;
6028        }
6029
6030        if (pid == MY_PID) {
6031            return PackageManager.PERMISSION_GRANTED;
6032        }
6033
6034        return ActivityManager.checkComponentPermission(permission, uid,
6035                owningUid, exported);
6036    }
6037
6038    /**
6039     * As the only public entry point for permissions checking, this method
6040     * can enforce the semantic that requesting a check on a null global
6041     * permission is automatically denied.  (Internally a null permission
6042     * string is used when calling {@link #checkComponentPermission} in cases
6043     * when only uid-based security is needed.)
6044     *
6045     * This can be called with or without the global lock held.
6046     */
6047    @Override
6048    public int checkPermission(String permission, int pid, int uid) {
6049        if (permission == null) {
6050            return PackageManager.PERMISSION_DENIED;
6051        }
6052        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6053    }
6054
6055    /**
6056     * Binder IPC calls go through the public entry point.
6057     * This can be called with or without the global lock held.
6058     */
6059    int checkCallingPermission(String permission) {
6060        return checkPermission(permission,
6061                Binder.getCallingPid(),
6062                UserHandle.getAppId(Binder.getCallingUid()));
6063    }
6064
6065    /**
6066     * This can be called with or without the global lock held.
6067     */
6068    void enforceCallingPermission(String permission, String func) {
6069        if (checkCallingPermission(permission)
6070                == PackageManager.PERMISSION_GRANTED) {
6071            return;
6072        }
6073
6074        String msg = "Permission Denial: " + func + " from pid="
6075                + Binder.getCallingPid()
6076                + ", uid=" + Binder.getCallingUid()
6077                + " requires " + permission;
6078        Slog.w(TAG, msg);
6079        throw new SecurityException(msg);
6080    }
6081
6082    /**
6083     * Determine if UID is holding permissions required to access {@link Uri} in
6084     * the given {@link ProviderInfo}. Final permission checking is always done
6085     * in {@link ContentProvider}.
6086     */
6087    private final boolean checkHoldingPermissionsLocked(
6088            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6089        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6090                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6091        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6092            return false;
6093        }
6094
6095        if (pi.applicationInfo.uid == uid) {
6096            return true;
6097        } else if (!pi.exported) {
6098            return false;
6099        }
6100
6101        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6102        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6103        try {
6104            // check if target holds top-level <provider> permissions
6105            if (!readMet && pi.readPermission != null
6106                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6107                readMet = true;
6108            }
6109            if (!writeMet && pi.writePermission != null
6110                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6111                writeMet = true;
6112            }
6113
6114            // track if unprotected read/write is allowed; any denied
6115            // <path-permission> below removes this ability
6116            boolean allowDefaultRead = pi.readPermission == null;
6117            boolean allowDefaultWrite = pi.writePermission == null;
6118
6119            // check if target holds any <path-permission> that match uri
6120            final PathPermission[] pps = pi.pathPermissions;
6121            if (pps != null) {
6122                final String path = grantUri.uri.getPath();
6123                int i = pps.length;
6124                while (i > 0 && (!readMet || !writeMet)) {
6125                    i--;
6126                    PathPermission pp = pps[i];
6127                    if (pp.match(path)) {
6128                        if (!readMet) {
6129                            final String pprperm = pp.getReadPermission();
6130                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6131                                    + pprperm + " for " + pp.getPath()
6132                                    + ": match=" + pp.match(path)
6133                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6134                            if (pprperm != null) {
6135                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6136                                    readMet = true;
6137                                } else {
6138                                    allowDefaultRead = false;
6139                                }
6140                            }
6141                        }
6142                        if (!writeMet) {
6143                            final String ppwperm = pp.getWritePermission();
6144                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6145                                    + ppwperm + " for " + pp.getPath()
6146                                    + ": match=" + pp.match(path)
6147                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6148                            if (ppwperm != null) {
6149                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6150                                    writeMet = true;
6151                                } else {
6152                                    allowDefaultWrite = false;
6153                                }
6154                            }
6155                        }
6156                    }
6157                }
6158            }
6159
6160            // grant unprotected <provider> read/write, if not blocked by
6161            // <path-permission> above
6162            if (allowDefaultRead) readMet = true;
6163            if (allowDefaultWrite) writeMet = true;
6164
6165        } catch (RemoteException e) {
6166            return false;
6167        }
6168
6169        return readMet && writeMet;
6170    }
6171
6172    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6173        ProviderInfo pi = null;
6174        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6175        if (cpr != null) {
6176            pi = cpr.info;
6177        } else {
6178            try {
6179                pi = AppGlobals.getPackageManager().resolveContentProvider(
6180                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6181            } catch (RemoteException ex) {
6182            }
6183        }
6184        return pi;
6185    }
6186
6187    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6188        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6189        if (targetUris != null) {
6190            return targetUris.get(grantUri);
6191        }
6192        return null;
6193    }
6194
6195    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6196            String targetPkg, int targetUid, GrantUri grantUri) {
6197        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6198        if (targetUris == null) {
6199            targetUris = Maps.newArrayMap();
6200            mGrantedUriPermissions.put(targetUid, targetUris);
6201        }
6202
6203        UriPermission perm = targetUris.get(grantUri);
6204        if (perm == null) {
6205            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6206            targetUris.put(grantUri, perm);
6207        }
6208
6209        return perm;
6210    }
6211
6212    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6213            final int modeFlags) {
6214        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6215        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6216                : UriPermission.STRENGTH_OWNED;
6217
6218        // Root gets to do everything.
6219        if (uid == 0) {
6220            return true;
6221        }
6222
6223        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6224        if (perms == null) return false;
6225
6226        // First look for exact match
6227        final UriPermission exactPerm = perms.get(grantUri);
6228        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6229            return true;
6230        }
6231
6232        // No exact match, look for prefixes
6233        final int N = perms.size();
6234        for (int i = 0; i < N; i++) {
6235            final UriPermission perm = perms.valueAt(i);
6236            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6237                    && perm.getStrength(modeFlags) >= minStrength) {
6238                return true;
6239            }
6240        }
6241
6242        return false;
6243    }
6244
6245    @Override
6246    public int checkUriPermission(Uri uri, int pid, int uid,
6247            final int modeFlags, int userId) {
6248        enforceNotIsolatedCaller("checkUriPermission");
6249
6250        // Another redirected-binder-call permissions check as in
6251        // {@link checkComponentPermission}.
6252        Identity tlsIdentity = sCallerIdentity.get();
6253        if (tlsIdentity != null) {
6254            uid = tlsIdentity.uid;
6255            pid = tlsIdentity.pid;
6256        }
6257
6258        // Our own process gets to do everything.
6259        if (pid == MY_PID) {
6260            return PackageManager.PERMISSION_GRANTED;
6261        }
6262        synchronized (this) {
6263            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6264                    ? PackageManager.PERMISSION_GRANTED
6265                    : PackageManager.PERMISSION_DENIED;
6266        }
6267    }
6268
6269    /**
6270     * Check if the targetPkg can be granted permission to access uri by
6271     * the callingUid using the given modeFlags.  Throws a security exception
6272     * if callingUid is not allowed to do this.  Returns the uid of the target
6273     * if the URI permission grant should be performed; returns -1 if it is not
6274     * needed (for example targetPkg already has permission to access the URI).
6275     * If you already know the uid of the target, you can supply it in
6276     * lastTargetUid else set that to -1.
6277     */
6278    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6279            final int modeFlags, int lastTargetUid) {
6280        if (!Intent.isAccessUriMode(modeFlags)) {
6281            return -1;
6282        }
6283
6284        if (targetPkg != null) {
6285            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6286                    "Checking grant " + targetPkg + " permission to " + grantUri);
6287        }
6288
6289        final IPackageManager pm = AppGlobals.getPackageManager();
6290
6291        // If this is not a content: uri, we can't do anything with it.
6292        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6293            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6294                    "Can't grant URI permission for non-content URI: " + grantUri);
6295            return -1;
6296        }
6297
6298        final String authority = grantUri.uri.getAuthority();
6299        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6300        if (pi == null) {
6301            Slog.w(TAG, "No content provider found for permission check: " +
6302                    grantUri.uri.toSafeString());
6303            return -1;
6304        }
6305
6306        int targetUid = lastTargetUid;
6307        if (targetUid < 0 && targetPkg != null) {
6308            try {
6309                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6310                if (targetUid < 0) {
6311                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6312                            "Can't grant URI permission no uid for: " + targetPkg);
6313                    return -1;
6314                }
6315            } catch (RemoteException ex) {
6316                return -1;
6317            }
6318        }
6319
6320        if (targetUid >= 0) {
6321            // First...  does the target actually need this permission?
6322            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6323                // No need to grant the target this permission.
6324                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6325                        "Target " + targetPkg + " already has full permission to " + grantUri);
6326                return -1;
6327            }
6328        } else {
6329            // First...  there is no target package, so can anyone access it?
6330            boolean allowed = pi.exported;
6331            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6332                if (pi.readPermission != null) {
6333                    allowed = false;
6334                }
6335            }
6336            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6337                if (pi.writePermission != null) {
6338                    allowed = false;
6339                }
6340            }
6341            if (allowed) {
6342                return -1;
6343            }
6344        }
6345
6346        // Second...  is the provider allowing granting of URI permissions?
6347        if (!pi.grantUriPermissions) {
6348            throw new SecurityException("Provider " + pi.packageName
6349                    + "/" + pi.name
6350                    + " does not allow granting of Uri permissions (uri "
6351                    + grantUri + ")");
6352        }
6353        if (pi.uriPermissionPatterns != null) {
6354            final int N = pi.uriPermissionPatterns.length;
6355            boolean allowed = false;
6356            for (int i=0; i<N; i++) {
6357                if (pi.uriPermissionPatterns[i] != null
6358                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6359                    allowed = true;
6360                    break;
6361                }
6362            }
6363            if (!allowed) {
6364                throw new SecurityException("Provider " + pi.packageName
6365                        + "/" + pi.name
6366                        + " does not allow granting of permission to path of Uri "
6367                        + grantUri);
6368            }
6369        }
6370
6371        // Third...  does the caller itself have permission to access
6372        // this uri?
6373        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6374            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6375                // Require they hold a strong enough Uri permission
6376                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6377                    throw new SecurityException("Uid " + callingUid
6378                            + " does not have permission to uri " + grantUri);
6379                }
6380            }
6381        }
6382        return targetUid;
6383    }
6384
6385    @Override
6386    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6387            final int modeFlags, int userId) {
6388        enforceNotIsolatedCaller("checkGrantUriPermission");
6389        synchronized(this) {
6390            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6391                    new GrantUri(userId, uri, false), modeFlags, -1);
6392        }
6393    }
6394
6395    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6396            final int modeFlags, UriPermissionOwner owner) {
6397        if (!Intent.isAccessUriMode(modeFlags)) {
6398            return;
6399        }
6400
6401        // So here we are: the caller has the assumed permission
6402        // to the uri, and the target doesn't.  Let's now give this to
6403        // the target.
6404
6405        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6406                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6407
6408        final String authority = grantUri.uri.getAuthority();
6409        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6410        if (pi == null) {
6411            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6412            return;
6413        }
6414
6415        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6416            grantUri.prefix = true;
6417        }
6418        final UriPermission perm = findOrCreateUriPermissionLocked(
6419                pi.packageName, targetPkg, targetUid, grantUri);
6420        perm.grantModes(modeFlags, owner);
6421    }
6422
6423    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6424            final int modeFlags, UriPermissionOwner owner) {
6425        if (targetPkg == null) {
6426            throw new NullPointerException("targetPkg");
6427        }
6428
6429        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6430                -1);
6431        if (targetUid < 0) {
6432            return;
6433        }
6434
6435        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6436                owner);
6437    }
6438
6439    static class NeededUriGrants extends ArrayList<GrantUri> {
6440        final String targetPkg;
6441        final int targetUid;
6442        final int flags;
6443
6444        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6445            this.targetPkg = targetPkg;
6446            this.targetUid = targetUid;
6447            this.flags = flags;
6448        }
6449    }
6450
6451    /**
6452     * Like checkGrantUriPermissionLocked, but takes an Intent.
6453     */
6454    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6455            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6456        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6457                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6458                + " clip=" + (intent != null ? intent.getClipData() : null)
6459                + " from " + intent + "; flags=0x"
6460                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6461
6462        if (targetPkg == null) {
6463            throw new NullPointerException("targetPkg");
6464        }
6465
6466        if (intent == null) {
6467            return null;
6468        }
6469        Uri data = intent.getData();
6470        ClipData clip = intent.getClipData();
6471        if (data == null && clip == null) {
6472            return null;
6473        }
6474        final IPackageManager pm = AppGlobals.getPackageManager();
6475        int targetUid;
6476        if (needed != null) {
6477            targetUid = needed.targetUid;
6478        } else {
6479            try {
6480                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6481            } catch (RemoteException ex) {
6482                return null;
6483            }
6484            if (targetUid < 0) {
6485                if (DEBUG_URI_PERMISSION) {
6486                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6487                            + " on user " + targetUserId);
6488                }
6489                return null;
6490            }
6491        }
6492        if (data != null) {
6493            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6494            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6495                    targetUid);
6496            if (targetUid > 0) {
6497                if (needed == null) {
6498                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6499                }
6500                needed.add(grantUri);
6501            }
6502        }
6503        if (clip != null) {
6504            for (int i=0; i<clip.getItemCount(); i++) {
6505                Uri uri = clip.getItemAt(i).getUri();
6506                if (uri != null) {
6507                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6508                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6509                            targetUid);
6510                    if (targetUid > 0) {
6511                        if (needed == null) {
6512                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6513                        }
6514                        needed.add(grantUri);
6515                    }
6516                } else {
6517                    Intent clipIntent = clip.getItemAt(i).getIntent();
6518                    if (clipIntent != null) {
6519                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6520                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6521                        if (newNeeded != null) {
6522                            needed = newNeeded;
6523                        }
6524                    }
6525                }
6526            }
6527        }
6528
6529        return needed;
6530    }
6531
6532    /**
6533     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6534     */
6535    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6536            UriPermissionOwner owner) {
6537        if (needed != null) {
6538            for (int i=0; i<needed.size(); i++) {
6539                GrantUri grantUri = needed.get(i);
6540                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6541                        grantUri, needed.flags, owner);
6542            }
6543        }
6544    }
6545
6546    void grantUriPermissionFromIntentLocked(int callingUid,
6547            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6548        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6549                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6550        if (needed == null) {
6551            return;
6552        }
6553
6554        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6555    }
6556
6557    @Override
6558    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6559            final int modeFlags, int userId) {
6560        enforceNotIsolatedCaller("grantUriPermission");
6561        GrantUri grantUri = new GrantUri(userId, uri, false);
6562        synchronized(this) {
6563            final ProcessRecord r = getRecordForAppLocked(caller);
6564            if (r == null) {
6565                throw new SecurityException("Unable to find app for caller "
6566                        + caller
6567                        + " when granting permission to uri " + grantUri);
6568            }
6569            if (targetPkg == null) {
6570                throw new IllegalArgumentException("null target");
6571            }
6572            if (grantUri == null) {
6573                throw new IllegalArgumentException("null uri");
6574            }
6575
6576            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6577                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6578                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6579                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6580
6581            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6582        }
6583    }
6584
6585    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6586        if (perm.modeFlags == 0) {
6587            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6588                    perm.targetUid);
6589            if (perms != null) {
6590                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6591                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6592
6593                perms.remove(perm.uri);
6594                if (perms.isEmpty()) {
6595                    mGrantedUriPermissions.remove(perm.targetUid);
6596                }
6597            }
6598        }
6599    }
6600
6601    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6602        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6603
6604        final IPackageManager pm = AppGlobals.getPackageManager();
6605        final String authority = grantUri.uri.getAuthority();
6606        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6607        if (pi == null) {
6608            Slog.w(TAG, "No content provider found for permission revoke: "
6609                    + grantUri.toSafeString());
6610            return;
6611        }
6612
6613        // Does the caller have this permission on the URI?
6614        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6615            // Right now, if you are not the original owner of the permission,
6616            // you are not allowed to revoke it.
6617            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6618                throw new SecurityException("Uid " + callingUid
6619                        + " does not have permission to uri " + grantUri);
6620            //}
6621        }
6622
6623        boolean persistChanged = false;
6624
6625        // Go through all of the permissions and remove any that match.
6626        int N = mGrantedUriPermissions.size();
6627        for (int i = 0; i < N; i++) {
6628            final int targetUid = mGrantedUriPermissions.keyAt(i);
6629            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6630
6631            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6632                final UriPermission perm = it.next();
6633                if (perm.uri.sourceUserId == grantUri.sourceUserId
6634                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6635                    if (DEBUG_URI_PERMISSION)
6636                        Slog.v(TAG,
6637                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6638                    persistChanged |= perm.revokeModes(
6639                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6640                    if (perm.modeFlags == 0) {
6641                        it.remove();
6642                    }
6643                }
6644            }
6645
6646            if (perms.isEmpty()) {
6647                mGrantedUriPermissions.remove(targetUid);
6648                N--;
6649                i--;
6650            }
6651        }
6652
6653        if (persistChanged) {
6654            schedulePersistUriGrants();
6655        }
6656    }
6657
6658    @Override
6659    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6660            int userId) {
6661        enforceNotIsolatedCaller("revokeUriPermission");
6662        synchronized(this) {
6663            final ProcessRecord r = getRecordForAppLocked(caller);
6664            if (r == null) {
6665                throw new SecurityException("Unable to find app for caller "
6666                        + caller
6667                        + " when revoking permission to uri " + uri);
6668            }
6669            if (uri == null) {
6670                Slog.w(TAG, "revokeUriPermission: null uri");
6671                return;
6672            }
6673
6674            if (!Intent.isAccessUriMode(modeFlags)) {
6675                return;
6676            }
6677
6678            final IPackageManager pm = AppGlobals.getPackageManager();
6679            final String authority = uri.getAuthority();
6680            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6681            if (pi == null) {
6682                Slog.w(TAG, "No content provider found for permission revoke: "
6683                        + uri.toSafeString());
6684                return;
6685            }
6686
6687            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6688        }
6689    }
6690
6691    /**
6692     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6693     * given package.
6694     *
6695     * @param packageName Package name to match, or {@code null} to apply to all
6696     *            packages.
6697     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6698     *            to all users.
6699     * @param persistable If persistable grants should be removed.
6700     */
6701    private void removeUriPermissionsForPackageLocked(
6702            String packageName, int userHandle, boolean persistable) {
6703        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6704            throw new IllegalArgumentException("Must narrow by either package or user");
6705        }
6706
6707        boolean persistChanged = false;
6708
6709        int N = mGrantedUriPermissions.size();
6710        for (int i = 0; i < N; i++) {
6711            final int targetUid = mGrantedUriPermissions.keyAt(i);
6712            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6713
6714            // Only inspect grants matching user
6715            if (userHandle == UserHandle.USER_ALL
6716                    || userHandle == UserHandle.getUserId(targetUid)) {
6717                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6718                    final UriPermission perm = it.next();
6719
6720                    // Only inspect grants matching package
6721                    if (packageName == null || perm.sourcePkg.equals(packageName)
6722                            || perm.targetPkg.equals(packageName)) {
6723                        persistChanged |= perm.revokeModes(
6724                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6725
6726                        // Only remove when no modes remain; any persisted grants
6727                        // will keep this alive.
6728                        if (perm.modeFlags == 0) {
6729                            it.remove();
6730                        }
6731                    }
6732                }
6733
6734                if (perms.isEmpty()) {
6735                    mGrantedUriPermissions.remove(targetUid);
6736                    N--;
6737                    i--;
6738                }
6739            }
6740        }
6741
6742        if (persistChanged) {
6743            schedulePersistUriGrants();
6744        }
6745    }
6746
6747    @Override
6748    public IBinder newUriPermissionOwner(String name) {
6749        enforceNotIsolatedCaller("newUriPermissionOwner");
6750        synchronized(this) {
6751            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6752            return owner.getExternalTokenLocked();
6753        }
6754    }
6755
6756    @Override
6757    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6758            final int modeFlags, int userId) {
6759        synchronized(this) {
6760            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6761            if (owner == null) {
6762                throw new IllegalArgumentException("Unknown owner: " + token);
6763            }
6764            if (fromUid != Binder.getCallingUid()) {
6765                if (Binder.getCallingUid() != Process.myUid()) {
6766                    // Only system code can grant URI permissions on behalf
6767                    // of other users.
6768                    throw new SecurityException("nice try");
6769                }
6770            }
6771            if (targetPkg == null) {
6772                throw new IllegalArgumentException("null target");
6773            }
6774            if (uri == null) {
6775                throw new IllegalArgumentException("null uri");
6776            }
6777
6778            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6779                    modeFlags, owner);
6780        }
6781    }
6782
6783    @Override
6784    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6785        synchronized(this) {
6786            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6787            if (owner == null) {
6788                throw new IllegalArgumentException("Unknown owner: " + token);
6789            }
6790
6791            if (uri == null) {
6792                owner.removeUriPermissionsLocked(mode);
6793            } else {
6794                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6795            }
6796        }
6797    }
6798
6799    private void schedulePersistUriGrants() {
6800        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6801            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6802                    10 * DateUtils.SECOND_IN_MILLIS);
6803        }
6804    }
6805
6806    private void writeGrantedUriPermissions() {
6807        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6808
6809        // Snapshot permissions so we can persist without lock
6810        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6811        synchronized (this) {
6812            final int size = mGrantedUriPermissions.size();
6813            for (int i = 0; i < size; i++) {
6814                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6815                for (UriPermission perm : perms.values()) {
6816                    if (perm.persistedModeFlags != 0) {
6817                        persist.add(perm.snapshot());
6818                    }
6819                }
6820            }
6821        }
6822
6823        FileOutputStream fos = null;
6824        try {
6825            fos = mGrantFile.startWrite();
6826
6827            XmlSerializer out = new FastXmlSerializer();
6828            out.setOutput(fos, "utf-8");
6829            out.startDocument(null, true);
6830            out.startTag(null, TAG_URI_GRANTS);
6831            for (UriPermission.Snapshot perm : persist) {
6832                out.startTag(null, TAG_URI_GRANT);
6833                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6834                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6835                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6836                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6837                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6838                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6839                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6840                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6841                out.endTag(null, TAG_URI_GRANT);
6842            }
6843            out.endTag(null, TAG_URI_GRANTS);
6844            out.endDocument();
6845
6846            mGrantFile.finishWrite(fos);
6847        } catch (IOException e) {
6848            if (fos != null) {
6849                mGrantFile.failWrite(fos);
6850            }
6851        }
6852    }
6853
6854    private void readGrantedUriPermissionsLocked() {
6855        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6856
6857        final long now = System.currentTimeMillis();
6858
6859        FileInputStream fis = null;
6860        try {
6861            fis = mGrantFile.openRead();
6862            final XmlPullParser in = Xml.newPullParser();
6863            in.setInput(fis, null);
6864
6865            int type;
6866            while ((type = in.next()) != END_DOCUMENT) {
6867                final String tag = in.getName();
6868                if (type == START_TAG) {
6869                    if (TAG_URI_GRANT.equals(tag)) {
6870                        final int sourceUserId;
6871                        final int targetUserId;
6872                        final int userHandle = readIntAttribute(in,
6873                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6874                        if (userHandle != UserHandle.USER_NULL) {
6875                            // For backwards compatibility.
6876                            sourceUserId = userHandle;
6877                            targetUserId = userHandle;
6878                        } else {
6879                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6880                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6881                        }
6882                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6883                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6884                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6885                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6886                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6887                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6888
6889                        // Sanity check that provider still belongs to source package
6890                        final ProviderInfo pi = getProviderInfoLocked(
6891                                uri.getAuthority(), sourceUserId);
6892                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6893                            int targetUid = -1;
6894                            try {
6895                                targetUid = AppGlobals.getPackageManager()
6896                                        .getPackageUid(targetPkg, targetUserId);
6897                            } catch (RemoteException e) {
6898                            }
6899                            if (targetUid != -1) {
6900                                final UriPermission perm = findOrCreateUriPermissionLocked(
6901                                        sourcePkg, targetPkg, targetUid,
6902                                        new GrantUri(sourceUserId, uri, prefix));
6903                                perm.initPersistedModes(modeFlags, createdTime);
6904                            }
6905                        } else {
6906                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6907                                    + " but instead found " + pi);
6908                        }
6909                    }
6910                }
6911            }
6912        } catch (FileNotFoundException e) {
6913            // Missing grants is okay
6914        } catch (IOException e) {
6915            Log.wtf(TAG, "Failed reading Uri grants", e);
6916        } catch (XmlPullParserException e) {
6917            Log.wtf(TAG, "Failed reading Uri grants", e);
6918        } finally {
6919            IoUtils.closeQuietly(fis);
6920        }
6921    }
6922
6923    @Override
6924    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6925        enforceNotIsolatedCaller("takePersistableUriPermission");
6926
6927        Preconditions.checkFlagsArgument(modeFlags,
6928                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6929
6930        synchronized (this) {
6931            final int callingUid = Binder.getCallingUid();
6932            boolean persistChanged = false;
6933            GrantUri grantUri = new GrantUri(userId, uri, false);
6934
6935            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6936                    new GrantUri(userId, uri, false));
6937            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6938                    new GrantUri(userId, uri, true));
6939
6940            final boolean exactValid = (exactPerm != null)
6941                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6942            final boolean prefixValid = (prefixPerm != null)
6943                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6944
6945            if (!(exactValid || prefixValid)) {
6946                throw new SecurityException("No persistable permission grants found for UID "
6947                        + callingUid + " and Uri " + grantUri.toSafeString());
6948            }
6949
6950            if (exactValid) {
6951                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6952            }
6953            if (prefixValid) {
6954                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6955            }
6956
6957            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6958
6959            if (persistChanged) {
6960                schedulePersistUriGrants();
6961            }
6962        }
6963    }
6964
6965    @Override
6966    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6967        enforceNotIsolatedCaller("releasePersistableUriPermission");
6968
6969        Preconditions.checkFlagsArgument(modeFlags,
6970                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6971
6972        synchronized (this) {
6973            final int callingUid = Binder.getCallingUid();
6974            boolean persistChanged = false;
6975
6976            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6977                    new GrantUri(userId, uri, false));
6978            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6979                    new GrantUri(userId, uri, true));
6980            if (exactPerm == null && prefixPerm == null) {
6981                throw new SecurityException("No permission grants found for UID " + callingUid
6982                        + " and Uri " + uri.toSafeString());
6983            }
6984
6985            if (exactPerm != null) {
6986                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6987                removeUriPermissionIfNeededLocked(exactPerm);
6988            }
6989            if (prefixPerm != null) {
6990                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6991                removeUriPermissionIfNeededLocked(prefixPerm);
6992            }
6993
6994            if (persistChanged) {
6995                schedulePersistUriGrants();
6996            }
6997        }
6998    }
6999
7000    /**
7001     * Prune any older {@link UriPermission} for the given UID until outstanding
7002     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7003     *
7004     * @return if any mutations occured that require persisting.
7005     */
7006    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7007        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7008        if (perms == null) return false;
7009        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7010
7011        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7012        for (UriPermission perm : perms.values()) {
7013            if (perm.persistedModeFlags != 0) {
7014                persisted.add(perm);
7015            }
7016        }
7017
7018        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7019        if (trimCount <= 0) return false;
7020
7021        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7022        for (int i = 0; i < trimCount; i++) {
7023            final UriPermission perm = persisted.get(i);
7024
7025            if (DEBUG_URI_PERMISSION) {
7026                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7027            }
7028
7029            perm.releasePersistableModes(~0);
7030            removeUriPermissionIfNeededLocked(perm);
7031        }
7032
7033        return true;
7034    }
7035
7036    @Override
7037    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7038            String packageName, boolean incoming) {
7039        enforceNotIsolatedCaller("getPersistedUriPermissions");
7040        Preconditions.checkNotNull(packageName, "packageName");
7041
7042        final int callingUid = Binder.getCallingUid();
7043        final IPackageManager pm = AppGlobals.getPackageManager();
7044        try {
7045            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7046            if (packageUid != callingUid) {
7047                throw new SecurityException(
7048                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7049            }
7050        } catch (RemoteException e) {
7051            throw new SecurityException("Failed to verify package name ownership");
7052        }
7053
7054        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7055        synchronized (this) {
7056            if (incoming) {
7057                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7058                        callingUid);
7059                if (perms == null) {
7060                    Slog.w(TAG, "No permission grants found for " + packageName);
7061                } else {
7062                    for (UriPermission perm : perms.values()) {
7063                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7064                            result.add(perm.buildPersistedPublicApiObject());
7065                        }
7066                    }
7067                }
7068            } else {
7069                final int size = mGrantedUriPermissions.size();
7070                for (int i = 0; i < size; i++) {
7071                    final ArrayMap<GrantUri, UriPermission> perms =
7072                            mGrantedUriPermissions.valueAt(i);
7073                    for (UriPermission perm : perms.values()) {
7074                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7075                            result.add(perm.buildPersistedPublicApiObject());
7076                        }
7077                    }
7078                }
7079            }
7080        }
7081        return new ParceledListSlice<android.content.UriPermission>(result);
7082    }
7083
7084    @Override
7085    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7086        synchronized (this) {
7087            ProcessRecord app =
7088                who != null ? getRecordForAppLocked(who) : null;
7089            if (app == null) return;
7090
7091            Message msg = Message.obtain();
7092            msg.what = WAIT_FOR_DEBUGGER_MSG;
7093            msg.obj = app;
7094            msg.arg1 = waiting ? 1 : 0;
7095            mHandler.sendMessage(msg);
7096        }
7097    }
7098
7099    @Override
7100    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7101        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7102        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7103        outInfo.availMem = Process.getFreeMemory();
7104        outInfo.totalMem = Process.getTotalMemory();
7105        outInfo.threshold = homeAppMem;
7106        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7107        outInfo.hiddenAppThreshold = cachedAppMem;
7108        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7109                ProcessList.SERVICE_ADJ);
7110        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7111                ProcessList.VISIBLE_APP_ADJ);
7112        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7113                ProcessList.FOREGROUND_APP_ADJ);
7114    }
7115
7116    // =========================================================
7117    // TASK MANAGEMENT
7118    // =========================================================
7119
7120    @Override
7121    public List<IAppTask> getAppTasks() {
7122        int callingUid = Binder.getCallingUid();
7123        long ident = Binder.clearCallingIdentity();
7124        synchronized(this) {
7125            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7126            try {
7127                if (localLOGV) Slog.v(TAG, "getAppTasks");
7128
7129                final int N = mRecentTasks.size();
7130                for (int i = 0; i < N; i++) {
7131                    TaskRecord tr = mRecentTasks.get(i);
7132                    // Skip tasks that are not created by the caller
7133                    if (tr.creatorUid == callingUid) {
7134                        ActivityManager.RecentTaskInfo taskInfo =
7135                                createRecentTaskInfoFromTaskRecord(tr);
7136                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7137                        list.add(taskImpl);
7138                    }
7139                }
7140            } finally {
7141                Binder.restoreCallingIdentity(ident);
7142            }
7143            return list;
7144        }
7145    }
7146
7147    @Override
7148    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7149        final int callingUid = Binder.getCallingUid();
7150        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7151
7152        synchronized(this) {
7153            if (localLOGV) Slog.v(
7154                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7155
7156            final boolean allowed = checkCallingPermission(
7157                    android.Manifest.permission.GET_TASKS)
7158                    == PackageManager.PERMISSION_GRANTED;
7159            if (!allowed) {
7160                Slog.w(TAG, "getTasks: caller " + callingUid
7161                        + " does not hold GET_TASKS; limiting output");
7162            }
7163
7164            // TODO: Improve with MRU list from all ActivityStacks.
7165            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7166        }
7167
7168        return list;
7169    }
7170
7171    TaskRecord getMostRecentTask() {
7172        return mRecentTasks.get(0);
7173    }
7174
7175    /**
7176     * Creates a new RecentTaskInfo from a TaskRecord.
7177     */
7178    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7179        // Update the task description to reflect any changes in the task stack
7180        tr.updateTaskDescription();
7181
7182        // Compose the recent task info
7183        ActivityManager.RecentTaskInfo rti
7184                = new ActivityManager.RecentTaskInfo();
7185        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7186        rti.persistentId = tr.taskId;
7187        rti.baseIntent = new Intent(tr.getBaseIntent());
7188        rti.origActivity = tr.origActivity;
7189        rti.description = tr.lastDescription;
7190        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7191        rti.userId = tr.userId;
7192        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7193        return rti;
7194    }
7195
7196    @Override
7197    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7198            int flags, int userId) {
7199        final int callingUid = Binder.getCallingUid();
7200        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7201                false, true, "getRecentTasks", null);
7202
7203        synchronized (this) {
7204            final boolean allowed = checkCallingPermission(
7205                    android.Manifest.permission.GET_TASKS)
7206                    == PackageManager.PERMISSION_GRANTED;
7207            if (!allowed) {
7208                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7209                        + " does not hold GET_TASKS; limiting output");
7210            }
7211            final boolean detailed = checkCallingPermission(
7212                    android.Manifest.permission.GET_DETAILED_TASKS)
7213                    == PackageManager.PERMISSION_GRANTED;
7214
7215            IPackageManager pm = AppGlobals.getPackageManager();
7216
7217            final int N = mRecentTasks.size();
7218            ArrayList<ActivityManager.RecentTaskInfo> res
7219                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7220                            maxNum < N ? maxNum : N);
7221
7222            final Set<Integer> includedUsers;
7223            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7224                includedUsers = getProfileIdsLocked(userId);
7225            } else {
7226                includedUsers = new HashSet<Integer>();
7227            }
7228            includedUsers.add(Integer.valueOf(userId));
7229            for (int i=0; i<N && maxNum > 0; i++) {
7230                TaskRecord tr = mRecentTasks.get(i);
7231                // Only add calling user or related users recent tasks
7232                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7233
7234                // Return the entry if desired by the caller.  We always return
7235                // the first entry, because callers always expect this to be the
7236                // foreground app.  We may filter others if the caller has
7237                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7238                // we should exclude the entry.
7239
7240                if (i == 0
7241                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7242                        || (tr.intent == null)
7243                        || ((tr.intent.getFlags()
7244                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7245                    if (!allowed) {
7246                        // If the caller doesn't have the GET_TASKS permission, then only
7247                        // allow them to see a small subset of tasks -- their own and home.
7248                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7249                            continue;
7250                        }
7251                    }
7252
7253                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7254                    if (!detailed) {
7255                        rti.baseIntent.replaceExtras((Bundle)null);
7256                    }
7257
7258                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7259                        // Check whether this activity is currently available.
7260                        try {
7261                            if (rti.origActivity != null) {
7262                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7263                                        == null) {
7264                                    continue;
7265                                }
7266                            } else if (rti.baseIntent != null) {
7267                                if (pm.queryIntentActivities(rti.baseIntent,
7268                                        null, 0, userId) == null) {
7269                                    continue;
7270                                }
7271                            }
7272                        } catch (RemoteException e) {
7273                            // Will never happen.
7274                        }
7275                    }
7276
7277                    res.add(rti);
7278                    maxNum--;
7279                }
7280            }
7281            return res;
7282        }
7283    }
7284
7285    private TaskRecord recentTaskForIdLocked(int id) {
7286        final int N = mRecentTasks.size();
7287            for (int i=0; i<N; i++) {
7288                TaskRecord tr = mRecentTasks.get(i);
7289                if (tr.taskId == id) {
7290                    return tr;
7291                }
7292            }
7293            return null;
7294    }
7295
7296    @Override
7297    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7298        synchronized (this) {
7299            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7300                    "getTaskThumbnails()");
7301            TaskRecord tr = recentTaskForIdLocked(id);
7302            if (tr != null) {
7303                return tr.getTaskThumbnailsLocked();
7304            }
7305        }
7306        return null;
7307    }
7308
7309    @Override
7310    public Bitmap getTaskTopThumbnail(int id) {
7311        synchronized (this) {
7312            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7313                    "getTaskTopThumbnail()");
7314            TaskRecord tr = recentTaskForIdLocked(id);
7315            if (tr != null) {
7316                return tr.getTaskTopThumbnailLocked();
7317            }
7318        }
7319        return null;
7320    }
7321
7322    @Override
7323    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7324        synchronized (this) {
7325            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7326            if (r != null) {
7327                r.taskDescription = td;
7328                r.task.updateTaskDescription();
7329            }
7330        }
7331    }
7332
7333    @Override
7334    public boolean removeSubTask(int taskId, int subTaskIndex) {
7335        synchronized (this) {
7336            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7337                    "removeSubTask()");
7338            long ident = Binder.clearCallingIdentity();
7339            try {
7340                TaskRecord tr = recentTaskForIdLocked(taskId);
7341                if (tr != null) {
7342                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7343                }
7344                return false;
7345            } finally {
7346                Binder.restoreCallingIdentity(ident);
7347            }
7348        }
7349    }
7350
7351    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7352        if (!pr.killedByAm) {
7353            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7354            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7355                    pr.processName, pr.setAdj, reason);
7356            pr.killedByAm = true;
7357            Process.killProcessQuiet(pr.pid);
7358        }
7359    }
7360
7361    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7362        tr.disposeThumbnail();
7363        mRecentTasks.remove(tr);
7364        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7365        Intent baseIntent = new Intent(
7366                tr.intent != null ? tr.intent : tr.affinityIntent);
7367        ComponentName component = baseIntent.getComponent();
7368        if (component == null) {
7369            Slog.w(TAG, "Now component for base intent of task: " + tr);
7370            return;
7371        }
7372
7373        // Find any running services associated with this app.
7374        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7375
7376        if (killProcesses) {
7377            // Find any running processes associated with this app.
7378            final String pkg = component.getPackageName();
7379            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7380            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7381            for (int i=0; i<pmap.size(); i++) {
7382                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7383                for (int j=0; j<uids.size(); j++) {
7384                    ProcessRecord proc = uids.valueAt(j);
7385                    if (proc.userId != tr.userId) {
7386                        continue;
7387                    }
7388                    if (!proc.pkgList.containsKey(pkg)) {
7389                        continue;
7390                    }
7391                    procs.add(proc);
7392                }
7393            }
7394
7395            // Kill the running processes.
7396            for (int i=0; i<procs.size(); i++) {
7397                ProcessRecord pr = procs.get(i);
7398                if (pr == mHomeProcess) {
7399                    // Don't kill the home process along with tasks from the same package.
7400                    continue;
7401                }
7402                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7403                    killUnneededProcessLocked(pr, "remove task");
7404                } else {
7405                    pr.waitingToKill = "remove task";
7406                }
7407            }
7408        }
7409    }
7410
7411    /**
7412     * Removes the task with the specified task id.
7413     *
7414     * @param taskId Identifier of the task to be removed.
7415     * @param flags Additional operational flags.  May be 0 or
7416     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7417     * @return Returns true if the given task was found and removed.
7418     */
7419    private boolean removeTaskByIdLocked(int taskId, int flags) {
7420        TaskRecord tr = recentTaskForIdLocked(taskId);
7421        if (tr != null) {
7422            tr.removeTaskActivitiesLocked(-1, false);
7423            cleanUpRemovedTaskLocked(tr, flags);
7424            if (tr.isPersistable) {
7425                notifyTaskPersisterLocked(tr, true);
7426            }
7427            return true;
7428        }
7429        return false;
7430    }
7431
7432    @Override
7433    public boolean removeTask(int taskId, int flags) {
7434        synchronized (this) {
7435            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7436                    "removeTask()");
7437            long ident = Binder.clearCallingIdentity();
7438            try {
7439                return removeTaskByIdLocked(taskId, flags);
7440            } finally {
7441                Binder.restoreCallingIdentity(ident);
7442            }
7443        }
7444    }
7445
7446    /**
7447     * TODO: Add mController hook
7448     */
7449    @Override
7450    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7451        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7452                "moveTaskToFront()");
7453
7454        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7455        synchronized(this) {
7456            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7457                    Binder.getCallingUid(), "Task to front")) {
7458                ActivityOptions.abort(options);
7459                return;
7460            }
7461            final long origId = Binder.clearCallingIdentity();
7462            try {
7463                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7464                if (task == null) {
7465                    return;
7466                }
7467                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7468                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7469                    return;
7470                }
7471                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7472            } finally {
7473                Binder.restoreCallingIdentity(origId);
7474            }
7475            ActivityOptions.abort(options);
7476        }
7477    }
7478
7479    @Override
7480    public void moveTaskToBack(int taskId) {
7481        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7482                "moveTaskToBack()");
7483
7484        synchronized(this) {
7485            TaskRecord tr = recentTaskForIdLocked(taskId);
7486            if (tr != null) {
7487                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7488                ActivityStack stack = tr.stack;
7489                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7490                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7491                            Binder.getCallingUid(), "Task to back")) {
7492                        return;
7493                    }
7494                }
7495                final long origId = Binder.clearCallingIdentity();
7496                try {
7497                    stack.moveTaskToBackLocked(taskId, null);
7498                } finally {
7499                    Binder.restoreCallingIdentity(origId);
7500                }
7501            }
7502        }
7503    }
7504
7505    /**
7506     * Moves an activity, and all of the other activities within the same task, to the bottom
7507     * of the history stack.  The activity's order within the task is unchanged.
7508     *
7509     * @param token A reference to the activity we wish to move
7510     * @param nonRoot If false then this only works if the activity is the root
7511     *                of a task; if true it will work for any activity in a task.
7512     * @return Returns true if the move completed, false if not.
7513     */
7514    @Override
7515    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7516        enforceNotIsolatedCaller("moveActivityTaskToBack");
7517        synchronized(this) {
7518            final long origId = Binder.clearCallingIdentity();
7519            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7520            if (taskId >= 0) {
7521                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7522            }
7523            Binder.restoreCallingIdentity(origId);
7524        }
7525        return false;
7526    }
7527
7528    @Override
7529    public void moveTaskBackwards(int task) {
7530        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7531                "moveTaskBackwards()");
7532
7533        synchronized(this) {
7534            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7535                    Binder.getCallingUid(), "Task backwards")) {
7536                return;
7537            }
7538            final long origId = Binder.clearCallingIdentity();
7539            moveTaskBackwardsLocked(task);
7540            Binder.restoreCallingIdentity(origId);
7541        }
7542    }
7543
7544    private final void moveTaskBackwardsLocked(int task) {
7545        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7546    }
7547
7548    @Override
7549    public IBinder getHomeActivityToken() throws RemoteException {
7550        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7551                "getHomeActivityToken()");
7552        synchronized (this) {
7553            return mStackSupervisor.getHomeActivityToken();
7554        }
7555    }
7556
7557    @Override
7558    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7559            IActivityContainerCallback callback) throws RemoteException {
7560        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7561                "createActivityContainer()");
7562        synchronized (this) {
7563            if (parentActivityToken == null) {
7564                throw new IllegalArgumentException("parent token must not be null");
7565            }
7566            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7567            if (r == null) {
7568                return null;
7569            }
7570            if (callback == null) {
7571                throw new IllegalArgumentException("callback must not be null");
7572            }
7573            return mStackSupervisor.createActivityContainer(r, callback);
7574        }
7575    }
7576
7577    @Override
7578    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7579        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7580                "deleteActivityContainer()");
7581        synchronized (this) {
7582            mStackSupervisor.deleteActivityContainer(container);
7583        }
7584    }
7585
7586    @Override
7587    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7588            throws RemoteException {
7589        synchronized (this) {
7590            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7591            if (stack != null) {
7592                return stack.mActivityContainer;
7593            }
7594            return null;
7595        }
7596    }
7597
7598    @Override
7599    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7600        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7601                "moveTaskToStack()");
7602        if (stackId == HOME_STACK_ID) {
7603            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7604                    new RuntimeException("here").fillInStackTrace());
7605        }
7606        synchronized (this) {
7607            long ident = Binder.clearCallingIdentity();
7608            try {
7609                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7610                        + stackId + " toTop=" + toTop);
7611                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7612            } finally {
7613                Binder.restoreCallingIdentity(ident);
7614            }
7615        }
7616    }
7617
7618    @Override
7619    public void resizeStack(int stackBoxId, Rect bounds) {
7620        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7621                "resizeStackBox()");
7622        long ident = Binder.clearCallingIdentity();
7623        try {
7624            mWindowManager.resizeStack(stackBoxId, bounds);
7625        } finally {
7626            Binder.restoreCallingIdentity(ident);
7627        }
7628    }
7629
7630    @Override
7631    public List<StackInfo> getAllStackInfos() {
7632        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7633                "getAllStackInfos()");
7634        long ident = Binder.clearCallingIdentity();
7635        try {
7636            synchronized (this) {
7637                return mStackSupervisor.getAllStackInfosLocked();
7638            }
7639        } finally {
7640            Binder.restoreCallingIdentity(ident);
7641        }
7642    }
7643
7644    @Override
7645    public StackInfo getStackInfo(int stackId) {
7646        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7647                "getStackInfo()");
7648        long ident = Binder.clearCallingIdentity();
7649        try {
7650            synchronized (this) {
7651                return mStackSupervisor.getStackInfoLocked(stackId);
7652            }
7653        } finally {
7654            Binder.restoreCallingIdentity(ident);
7655        }
7656    }
7657
7658    @Override
7659    public boolean isInHomeStack(int taskId) {
7660        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7661                "getStackInfo()");
7662        long ident = Binder.clearCallingIdentity();
7663        try {
7664            synchronized (this) {
7665                TaskRecord tr = recentTaskForIdLocked(taskId);
7666                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7667            }
7668        } finally {
7669            Binder.restoreCallingIdentity(ident);
7670        }
7671    }
7672
7673    @Override
7674    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7675        synchronized(this) {
7676            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7677        }
7678    }
7679
7680    private boolean isLockTaskAuthorized(String pkg) {
7681        final DevicePolicyManager dpm = (DevicePolicyManager)
7682                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7683        try {
7684            int uid = mContext.getPackageManager().getPackageUid(pkg,
7685                    Binder.getCallingUserHandle().getIdentifier());
7686            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7687        } catch (NameNotFoundException e) {
7688            return false;
7689        }
7690    }
7691
7692    private void startLockTaskMode(TaskRecord task) {
7693        final String pkg;
7694        synchronized (this) {
7695            pkg = task.intent.getComponent().getPackageName();
7696        }
7697        if (!isLockTaskAuthorized(pkg)) {
7698            return;
7699        }
7700        long ident = Binder.clearCallingIdentity();
7701        try {
7702            synchronized (this) {
7703                // Since we lost lock on task, make sure it is still there.
7704                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7705                if (task != null) {
7706                    if ((mFocusedActivity == null) || (task != mFocusedActivity.task)) {
7707                        throw new IllegalArgumentException("Invalid task, not in foreground");
7708                    }
7709                    mStackSupervisor.setLockTaskModeLocked(task);
7710                }
7711            }
7712        } finally {
7713            Binder.restoreCallingIdentity(ident);
7714        }
7715    }
7716
7717    @Override
7718    public void startLockTaskMode(int taskId) {
7719        final TaskRecord task;
7720        long ident = Binder.clearCallingIdentity();
7721        try {
7722            synchronized (this) {
7723                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7724            }
7725        } finally {
7726            Binder.restoreCallingIdentity(ident);
7727        }
7728        if (task != null) {
7729            startLockTaskMode(task);
7730        }
7731    }
7732
7733    @Override
7734    public void startLockTaskMode(IBinder token) {
7735        final TaskRecord task;
7736        long ident = Binder.clearCallingIdentity();
7737        try {
7738            synchronized (this) {
7739                final ActivityRecord r = ActivityRecord.forToken(token);
7740                if (r == null) {
7741                    return;
7742                }
7743                task = r.task;
7744            }
7745        } finally {
7746            Binder.restoreCallingIdentity(ident);
7747        }
7748        if (task != null) {
7749            startLockTaskMode(task);
7750        }
7751    }
7752
7753    @Override
7754    public void stopLockTaskMode() {
7755        // Verify that the user matches the package of the intent for the TaskRecord
7756        // we are locked to.  This will ensure the same caller for startLockTaskMode and
7757        // stopLockTaskMode.
7758        try {
7759            String pkg = mStackSupervisor.mLockTaskModeTask.intent.getPackage();
7760            int uid = mContext.getPackageManager().getPackageUid(pkg,
7761                    Binder.getCallingUserHandle().getIdentifier());
7762            if (uid != Binder.getCallingUid()) {
7763                throw new SecurityException("Invalid uid, expected " + uid);
7764            }
7765        } catch (NameNotFoundException e) {
7766            Log.d(TAG, "stopLockTaskMode " + e);
7767            return;
7768        }
7769        // Stop lock task
7770        synchronized (this) {
7771            mStackSupervisor.setLockTaskModeLocked(null);
7772        }
7773    }
7774
7775    @Override
7776    public boolean isInLockTaskMode() {
7777        synchronized (this) {
7778            return mStackSupervisor.isInLockTaskMode();
7779        }
7780    }
7781
7782    // =========================================================
7783    // CONTENT PROVIDERS
7784    // =========================================================
7785
7786    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7787        List<ProviderInfo> providers = null;
7788        try {
7789            providers = AppGlobals.getPackageManager().
7790                queryContentProviders(app.processName, app.uid,
7791                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7792        } catch (RemoteException ex) {
7793        }
7794        if (DEBUG_MU)
7795            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7796        int userId = app.userId;
7797        if (providers != null) {
7798            int N = providers.size();
7799            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7800            for (int i=0; i<N; i++) {
7801                ProviderInfo cpi =
7802                    (ProviderInfo)providers.get(i);
7803                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7804                        cpi.name, cpi.flags);
7805                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7806                    // This is a singleton provider, but a user besides the
7807                    // default user is asking to initialize a process it runs
7808                    // in...  well, no, it doesn't actually run in this process,
7809                    // it runs in the process of the default user.  Get rid of it.
7810                    providers.remove(i);
7811                    N--;
7812                    i--;
7813                    continue;
7814                }
7815
7816                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7817                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7818                if (cpr == null) {
7819                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7820                    mProviderMap.putProviderByClass(comp, cpr);
7821                }
7822                if (DEBUG_MU)
7823                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7824                app.pubProviders.put(cpi.name, cpr);
7825                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7826                    // Don't add this if it is a platform component that is marked
7827                    // to run in multiple processes, because this is actually
7828                    // part of the framework so doesn't make sense to track as a
7829                    // separate apk in the process.
7830                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7831                            mProcessStats);
7832                }
7833                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7834            }
7835        }
7836        return providers;
7837    }
7838
7839    /**
7840     * Check if {@link ProcessRecord} has a possible chance at accessing the
7841     * given {@link ProviderInfo}. Final permission checking is always done
7842     * in {@link ContentProvider}.
7843     */
7844    private final String checkContentProviderPermissionLocked(
7845            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7846        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7847        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7848        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7849        // Looking for cross-user grants before to enforce the typical cross-users permissions
7850        if (userId != UserHandle.getUserId(callingUid)) {
7851            if (perms != null) {
7852                for (GrantUri grantUri : perms.keySet()) {
7853                    if (grantUri.sourceUserId == userId) {
7854                        String authority = grantUri.uri.getAuthority();
7855                        if (authority.equals(cpi.authority)) {
7856                            return null;
7857                        }
7858                    }
7859                }
7860            }
7861        }
7862        if (checkUser) {
7863            userId = handleIncomingUser(callingPid, callingUid, userId,
7864                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7865        }
7866        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7867                cpi.applicationInfo.uid, cpi.exported)
7868                == PackageManager.PERMISSION_GRANTED) {
7869            return null;
7870        }
7871        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7872                cpi.applicationInfo.uid, cpi.exported)
7873                == PackageManager.PERMISSION_GRANTED) {
7874            return null;
7875        }
7876
7877        PathPermission[] pps = cpi.pathPermissions;
7878        if (pps != null) {
7879            int i = pps.length;
7880            while (i > 0) {
7881                i--;
7882                PathPermission pp = pps[i];
7883                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7884                        cpi.applicationInfo.uid, cpi.exported)
7885                        == PackageManager.PERMISSION_GRANTED) {
7886                    return null;
7887                }
7888                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7889                        cpi.applicationInfo.uid, cpi.exported)
7890                        == PackageManager.PERMISSION_GRANTED) {
7891                    return null;
7892                }
7893            }
7894        }
7895
7896        if (perms != null) {
7897            for (GrantUri grantUri : perms.keySet()) {
7898                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7899                    return null;
7900                }
7901            }
7902        }
7903
7904        String msg;
7905        if (!cpi.exported) {
7906            msg = "Permission Denial: opening provider " + cpi.name
7907                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7908                    + ", uid=" + callingUid + ") that is not exported from uid "
7909                    + cpi.applicationInfo.uid;
7910        } else {
7911            msg = "Permission Denial: opening provider " + cpi.name
7912                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7913                    + ", uid=" + callingUid + ") requires "
7914                    + cpi.readPermission + " or " + cpi.writePermission;
7915        }
7916        Slog.w(TAG, msg);
7917        return msg;
7918    }
7919
7920    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7921            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7922        if (r != null) {
7923            for (int i=0; i<r.conProviders.size(); i++) {
7924                ContentProviderConnection conn = r.conProviders.get(i);
7925                if (conn.provider == cpr) {
7926                    if (DEBUG_PROVIDER) Slog.v(TAG,
7927                            "Adding provider requested by "
7928                            + r.processName + " from process "
7929                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7930                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7931                    if (stable) {
7932                        conn.stableCount++;
7933                        conn.numStableIncs++;
7934                    } else {
7935                        conn.unstableCount++;
7936                        conn.numUnstableIncs++;
7937                    }
7938                    return conn;
7939                }
7940            }
7941            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7942            if (stable) {
7943                conn.stableCount = 1;
7944                conn.numStableIncs = 1;
7945            } else {
7946                conn.unstableCount = 1;
7947                conn.numUnstableIncs = 1;
7948            }
7949            cpr.connections.add(conn);
7950            r.conProviders.add(conn);
7951            return conn;
7952        }
7953        cpr.addExternalProcessHandleLocked(externalProcessToken);
7954        return null;
7955    }
7956
7957    boolean decProviderCountLocked(ContentProviderConnection conn,
7958            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7959        if (conn != null) {
7960            cpr = conn.provider;
7961            if (DEBUG_PROVIDER) Slog.v(TAG,
7962                    "Removing provider requested by "
7963                    + conn.client.processName + " from process "
7964                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7965                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7966            if (stable) {
7967                conn.stableCount--;
7968            } else {
7969                conn.unstableCount--;
7970            }
7971            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7972                cpr.connections.remove(conn);
7973                conn.client.conProviders.remove(conn);
7974                return true;
7975            }
7976            return false;
7977        }
7978        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7979        return false;
7980    }
7981
7982    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7983            String name, IBinder token, boolean stable, int userId) {
7984        ContentProviderRecord cpr;
7985        ContentProviderConnection conn = null;
7986        ProviderInfo cpi = null;
7987
7988        synchronized(this) {
7989            ProcessRecord r = null;
7990            if (caller != null) {
7991                r = getRecordForAppLocked(caller);
7992                if (r == null) {
7993                    throw new SecurityException(
7994                            "Unable to find app for caller " + caller
7995                          + " (pid=" + Binder.getCallingPid()
7996                          + ") when getting content provider " + name);
7997                }
7998            }
7999
8000            boolean checkCrossUser = true;
8001
8002            // First check if this content provider has been published...
8003            cpr = mProviderMap.getProviderByName(name, userId);
8004            // If that didn't work, check if it exists for user 0 and then
8005            // verify that it's a singleton provider before using it.
8006            if (cpr == null && userId != UserHandle.USER_OWNER) {
8007                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8008                if (cpr != null) {
8009                    cpi = cpr.info;
8010                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8011                            cpi.name, cpi.flags)
8012                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8013                        userId = UserHandle.USER_OWNER;
8014                        checkCrossUser = false;
8015                    } else {
8016                        cpr = null;
8017                        cpi = null;
8018                    }
8019                }
8020            }
8021
8022            boolean providerRunning = cpr != null;
8023            if (providerRunning) {
8024                cpi = cpr.info;
8025                String msg;
8026                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8027                        != null) {
8028                    throw new SecurityException(msg);
8029                }
8030
8031                if (r != null && cpr.canRunHere(r)) {
8032                    // This provider has been published or is in the process
8033                    // of being published...  but it is also allowed to run
8034                    // in the caller's process, so don't make a connection
8035                    // and just let the caller instantiate its own instance.
8036                    ContentProviderHolder holder = cpr.newHolder(null);
8037                    // don't give caller the provider object, it needs
8038                    // to make its own.
8039                    holder.provider = null;
8040                    return holder;
8041                }
8042
8043                final long origId = Binder.clearCallingIdentity();
8044
8045                // In this case the provider instance already exists, so we can
8046                // return it right away.
8047                conn = incProviderCountLocked(r, cpr, token, stable);
8048                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8049                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8050                        // If this is a perceptible app accessing the provider,
8051                        // make sure to count it as being accessed and thus
8052                        // back up on the LRU list.  This is good because
8053                        // content providers are often expensive to start.
8054                        updateLruProcessLocked(cpr.proc, false, null);
8055                    }
8056                }
8057
8058                if (cpr.proc != null) {
8059                    if (false) {
8060                        if (cpr.name.flattenToShortString().equals(
8061                                "com.android.providers.calendar/.CalendarProvider2")) {
8062                            Slog.v(TAG, "****************** KILLING "
8063                                + cpr.name.flattenToShortString());
8064                            Process.killProcess(cpr.proc.pid);
8065                        }
8066                    }
8067                    boolean success = updateOomAdjLocked(cpr.proc);
8068                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8069                    // NOTE: there is still a race here where a signal could be
8070                    // pending on the process even though we managed to update its
8071                    // adj level.  Not sure what to do about this, but at least
8072                    // the race is now smaller.
8073                    if (!success) {
8074                        // Uh oh...  it looks like the provider's process
8075                        // has been killed on us.  We need to wait for a new
8076                        // process to be started, and make sure its death
8077                        // doesn't kill our process.
8078                        Slog.i(TAG,
8079                                "Existing provider " + cpr.name.flattenToShortString()
8080                                + " is crashing; detaching " + r);
8081                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8082                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8083                        if (!lastRef) {
8084                            // This wasn't the last ref our process had on
8085                            // the provider...  we have now been killed, bail.
8086                            return null;
8087                        }
8088                        providerRunning = false;
8089                        conn = null;
8090                    }
8091                }
8092
8093                Binder.restoreCallingIdentity(origId);
8094            }
8095
8096            boolean singleton;
8097            if (!providerRunning) {
8098                try {
8099                    cpi = AppGlobals.getPackageManager().
8100                        resolveContentProvider(name,
8101                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8102                } catch (RemoteException ex) {
8103                }
8104                if (cpi == null) {
8105                    return null;
8106                }
8107                // If the provider is a singleton AND
8108                // (it's a call within the same user || the provider is a
8109                // privileged app)
8110                // Then allow connecting to the singleton provider
8111                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8112                        cpi.name, cpi.flags)
8113                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8114                if (singleton) {
8115                    userId = UserHandle.USER_OWNER;
8116                }
8117                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8118
8119                String msg;
8120                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8121                        != null) {
8122                    throw new SecurityException(msg);
8123                }
8124
8125                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8126                        && !cpi.processName.equals("system")) {
8127                    // If this content provider does not run in the system
8128                    // process, and the system is not yet ready to run other
8129                    // processes, then fail fast instead of hanging.
8130                    throw new IllegalArgumentException(
8131                            "Attempt to launch content provider before system ready");
8132                }
8133
8134                // Make sure that the user who owns this provider is started.  If not,
8135                // we don't want to allow it to run.
8136                if (mStartedUsers.get(userId) == null) {
8137                    Slog.w(TAG, "Unable to launch app "
8138                            + cpi.applicationInfo.packageName + "/"
8139                            + cpi.applicationInfo.uid + " for provider "
8140                            + name + ": user " + userId + " is stopped");
8141                    return null;
8142                }
8143
8144                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8145                cpr = mProviderMap.getProviderByClass(comp, userId);
8146                final boolean firstClass = cpr == null;
8147                if (firstClass) {
8148                    try {
8149                        ApplicationInfo ai =
8150                            AppGlobals.getPackageManager().
8151                                getApplicationInfo(
8152                                        cpi.applicationInfo.packageName,
8153                                        STOCK_PM_FLAGS, userId);
8154                        if (ai == null) {
8155                            Slog.w(TAG, "No package info for content provider "
8156                                    + cpi.name);
8157                            return null;
8158                        }
8159                        ai = getAppInfoForUser(ai, userId);
8160                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8161                    } catch (RemoteException ex) {
8162                        // pm is in same process, this will never happen.
8163                    }
8164                }
8165
8166                if (r != null && cpr.canRunHere(r)) {
8167                    // If this is a multiprocess provider, then just return its
8168                    // info and allow the caller to instantiate it.  Only do
8169                    // this if the provider is the same user as the caller's
8170                    // process, or can run as root (so can be in any process).
8171                    return cpr.newHolder(null);
8172                }
8173
8174                if (DEBUG_PROVIDER) {
8175                    RuntimeException e = new RuntimeException("here");
8176                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8177                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8178                }
8179
8180                // This is single process, and our app is now connecting to it.
8181                // See if we are already in the process of launching this
8182                // provider.
8183                final int N = mLaunchingProviders.size();
8184                int i;
8185                for (i=0; i<N; i++) {
8186                    if (mLaunchingProviders.get(i) == cpr) {
8187                        break;
8188                    }
8189                }
8190
8191                // If the provider is not already being launched, then get it
8192                // started.
8193                if (i >= N) {
8194                    final long origId = Binder.clearCallingIdentity();
8195
8196                    try {
8197                        // Content provider is now in use, its package can't be stopped.
8198                        try {
8199                            AppGlobals.getPackageManager().setPackageStoppedState(
8200                                    cpr.appInfo.packageName, false, userId);
8201                        } catch (RemoteException e) {
8202                        } catch (IllegalArgumentException e) {
8203                            Slog.w(TAG, "Failed trying to unstop package "
8204                                    + cpr.appInfo.packageName + ": " + e);
8205                        }
8206
8207                        // Use existing process if already started
8208                        ProcessRecord proc = getProcessRecordLocked(
8209                                cpi.processName, cpr.appInfo.uid, false);
8210                        if (proc != null && proc.thread != null) {
8211                            if (DEBUG_PROVIDER) {
8212                                Slog.d(TAG, "Installing in existing process " + proc);
8213                            }
8214                            proc.pubProviders.put(cpi.name, cpr);
8215                            try {
8216                                proc.thread.scheduleInstallProvider(cpi);
8217                            } catch (RemoteException e) {
8218                            }
8219                        } else {
8220                            proc = startProcessLocked(cpi.processName,
8221                                    cpr.appInfo, false, 0, "content provider",
8222                                    new ComponentName(cpi.applicationInfo.packageName,
8223                                            cpi.name), false, false, false);
8224                            if (proc == null) {
8225                                Slog.w(TAG, "Unable to launch app "
8226                                        + cpi.applicationInfo.packageName + "/"
8227                                        + cpi.applicationInfo.uid + " for provider "
8228                                        + name + ": process is bad");
8229                                return null;
8230                            }
8231                        }
8232                        cpr.launchingApp = proc;
8233                        mLaunchingProviders.add(cpr);
8234                    } finally {
8235                        Binder.restoreCallingIdentity(origId);
8236                    }
8237                }
8238
8239                // Make sure the provider is published (the same provider class
8240                // may be published under multiple names).
8241                if (firstClass) {
8242                    mProviderMap.putProviderByClass(comp, cpr);
8243                }
8244
8245                mProviderMap.putProviderByName(name, cpr);
8246                conn = incProviderCountLocked(r, cpr, token, stable);
8247                if (conn != null) {
8248                    conn.waiting = true;
8249                }
8250            }
8251        }
8252
8253        // Wait for the provider to be published...
8254        synchronized (cpr) {
8255            while (cpr.provider == null) {
8256                if (cpr.launchingApp == null) {
8257                    Slog.w(TAG, "Unable to launch app "
8258                            + cpi.applicationInfo.packageName + "/"
8259                            + cpi.applicationInfo.uid + " for provider "
8260                            + name + ": launching app became null");
8261                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8262                            UserHandle.getUserId(cpi.applicationInfo.uid),
8263                            cpi.applicationInfo.packageName,
8264                            cpi.applicationInfo.uid, name);
8265                    return null;
8266                }
8267                try {
8268                    if (DEBUG_MU) {
8269                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8270                                + cpr.launchingApp);
8271                    }
8272                    if (conn != null) {
8273                        conn.waiting = true;
8274                    }
8275                    cpr.wait();
8276                } catch (InterruptedException ex) {
8277                } finally {
8278                    if (conn != null) {
8279                        conn.waiting = false;
8280                    }
8281                }
8282            }
8283        }
8284        return cpr != null ? cpr.newHolder(conn) : null;
8285    }
8286
8287    @Override
8288    public final ContentProviderHolder getContentProvider(
8289            IApplicationThread caller, String name, int userId, boolean stable) {
8290        enforceNotIsolatedCaller("getContentProvider");
8291        if (caller == null) {
8292            String msg = "null IApplicationThread when getting content provider "
8293                    + name;
8294            Slog.w(TAG, msg);
8295            throw new SecurityException(msg);
8296        }
8297        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8298        // with cross-user grant.
8299        return getContentProviderImpl(caller, name, null, stable, userId);
8300    }
8301
8302    public ContentProviderHolder getContentProviderExternal(
8303            String name, int userId, IBinder token) {
8304        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8305            "Do not have permission in call getContentProviderExternal()");
8306        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8307                false, true, "getContentProvider", null);
8308        return getContentProviderExternalUnchecked(name, token, userId);
8309    }
8310
8311    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8312            IBinder token, int userId) {
8313        return getContentProviderImpl(null, name, token, true, userId);
8314    }
8315
8316    /**
8317     * Drop a content provider from a ProcessRecord's bookkeeping
8318     */
8319    public void removeContentProvider(IBinder connection, boolean stable) {
8320        enforceNotIsolatedCaller("removeContentProvider");
8321        long ident = Binder.clearCallingIdentity();
8322        try {
8323            synchronized (this) {
8324                ContentProviderConnection conn;
8325                try {
8326                    conn = (ContentProviderConnection)connection;
8327                } catch (ClassCastException e) {
8328                    String msg ="removeContentProvider: " + connection
8329                            + " not a ContentProviderConnection";
8330                    Slog.w(TAG, msg);
8331                    throw new IllegalArgumentException(msg);
8332                }
8333                if (conn == null) {
8334                    throw new NullPointerException("connection is null");
8335                }
8336                if (decProviderCountLocked(conn, null, null, stable)) {
8337                    updateOomAdjLocked();
8338                }
8339            }
8340        } finally {
8341            Binder.restoreCallingIdentity(ident);
8342        }
8343    }
8344
8345    public void removeContentProviderExternal(String name, IBinder token) {
8346        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8347            "Do not have permission in call removeContentProviderExternal()");
8348        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8349    }
8350
8351    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8352        synchronized (this) {
8353            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8354            if(cpr == null) {
8355                //remove from mProvidersByClass
8356                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8357                return;
8358            }
8359
8360            //update content provider record entry info
8361            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8362            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8363            if (localCpr.hasExternalProcessHandles()) {
8364                if (localCpr.removeExternalProcessHandleLocked(token)) {
8365                    updateOomAdjLocked();
8366                } else {
8367                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8368                            + " with no external reference for token: "
8369                            + token + ".");
8370                }
8371            } else {
8372                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8373                        + " with no external references.");
8374            }
8375        }
8376    }
8377
8378    public final void publishContentProviders(IApplicationThread caller,
8379            List<ContentProviderHolder> providers) {
8380        if (providers == null) {
8381            return;
8382        }
8383
8384        enforceNotIsolatedCaller("publishContentProviders");
8385        synchronized (this) {
8386            final ProcessRecord r = getRecordForAppLocked(caller);
8387            if (DEBUG_MU)
8388                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8389            if (r == null) {
8390                throw new SecurityException(
8391                        "Unable to find app for caller " + caller
8392                      + " (pid=" + Binder.getCallingPid()
8393                      + ") when publishing content providers");
8394            }
8395
8396            final long origId = Binder.clearCallingIdentity();
8397
8398            final int N = providers.size();
8399            for (int i=0; i<N; i++) {
8400                ContentProviderHolder src = providers.get(i);
8401                if (src == null || src.info == null || src.provider == null) {
8402                    continue;
8403                }
8404                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8405                if (DEBUG_MU)
8406                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8407                if (dst != null) {
8408                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8409                    mProviderMap.putProviderByClass(comp, dst);
8410                    String names[] = dst.info.authority.split(";");
8411                    for (int j = 0; j < names.length; j++) {
8412                        mProviderMap.putProviderByName(names[j], dst);
8413                    }
8414
8415                    int NL = mLaunchingProviders.size();
8416                    int j;
8417                    for (j=0; j<NL; j++) {
8418                        if (mLaunchingProviders.get(j) == dst) {
8419                            mLaunchingProviders.remove(j);
8420                            j--;
8421                            NL--;
8422                        }
8423                    }
8424                    synchronized (dst) {
8425                        dst.provider = src.provider;
8426                        dst.proc = r;
8427                        dst.notifyAll();
8428                    }
8429                    updateOomAdjLocked(r);
8430                }
8431            }
8432
8433            Binder.restoreCallingIdentity(origId);
8434        }
8435    }
8436
8437    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8438        ContentProviderConnection conn;
8439        try {
8440            conn = (ContentProviderConnection)connection;
8441        } catch (ClassCastException e) {
8442            String msg ="refContentProvider: " + connection
8443                    + " not a ContentProviderConnection";
8444            Slog.w(TAG, msg);
8445            throw new IllegalArgumentException(msg);
8446        }
8447        if (conn == null) {
8448            throw new NullPointerException("connection is null");
8449        }
8450
8451        synchronized (this) {
8452            if (stable > 0) {
8453                conn.numStableIncs += stable;
8454            }
8455            stable = conn.stableCount + stable;
8456            if (stable < 0) {
8457                throw new IllegalStateException("stableCount < 0: " + stable);
8458            }
8459
8460            if (unstable > 0) {
8461                conn.numUnstableIncs += unstable;
8462            }
8463            unstable = conn.unstableCount + unstable;
8464            if (unstable < 0) {
8465                throw new IllegalStateException("unstableCount < 0: " + unstable);
8466            }
8467
8468            if ((stable+unstable) <= 0) {
8469                throw new IllegalStateException("ref counts can't go to zero here: stable="
8470                        + stable + " unstable=" + unstable);
8471            }
8472            conn.stableCount = stable;
8473            conn.unstableCount = unstable;
8474            return !conn.dead;
8475        }
8476    }
8477
8478    public void unstableProviderDied(IBinder connection) {
8479        ContentProviderConnection conn;
8480        try {
8481            conn = (ContentProviderConnection)connection;
8482        } catch (ClassCastException e) {
8483            String msg ="refContentProvider: " + connection
8484                    + " not a ContentProviderConnection";
8485            Slog.w(TAG, msg);
8486            throw new IllegalArgumentException(msg);
8487        }
8488        if (conn == null) {
8489            throw new NullPointerException("connection is null");
8490        }
8491
8492        // Safely retrieve the content provider associated with the connection.
8493        IContentProvider provider;
8494        synchronized (this) {
8495            provider = conn.provider.provider;
8496        }
8497
8498        if (provider == null) {
8499            // Um, yeah, we're way ahead of you.
8500            return;
8501        }
8502
8503        // Make sure the caller is being honest with us.
8504        if (provider.asBinder().pingBinder()) {
8505            // Er, no, still looks good to us.
8506            synchronized (this) {
8507                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8508                        + " says " + conn + " died, but we don't agree");
8509                return;
8510            }
8511        }
8512
8513        // Well look at that!  It's dead!
8514        synchronized (this) {
8515            if (conn.provider.provider != provider) {
8516                // But something changed...  good enough.
8517                return;
8518            }
8519
8520            ProcessRecord proc = conn.provider.proc;
8521            if (proc == null || proc.thread == null) {
8522                // Seems like the process is already cleaned up.
8523                return;
8524            }
8525
8526            // As far as we're concerned, this is just like receiving a
8527            // death notification...  just a bit prematurely.
8528            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8529                    + ") early provider death");
8530            final long ident = Binder.clearCallingIdentity();
8531            try {
8532                appDiedLocked(proc, proc.pid, proc.thread);
8533            } finally {
8534                Binder.restoreCallingIdentity(ident);
8535            }
8536        }
8537    }
8538
8539    @Override
8540    public void appNotRespondingViaProvider(IBinder connection) {
8541        enforceCallingPermission(
8542                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8543
8544        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8545        if (conn == null) {
8546            Slog.w(TAG, "ContentProviderConnection is null");
8547            return;
8548        }
8549
8550        final ProcessRecord host = conn.provider.proc;
8551        if (host == null) {
8552            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8553            return;
8554        }
8555
8556        final long token = Binder.clearCallingIdentity();
8557        try {
8558            appNotResponding(host, null, null, false, "ContentProvider not responding");
8559        } finally {
8560            Binder.restoreCallingIdentity(token);
8561        }
8562    }
8563
8564    public final void installSystemProviders() {
8565        List<ProviderInfo> providers;
8566        synchronized (this) {
8567            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8568            providers = generateApplicationProvidersLocked(app);
8569            if (providers != null) {
8570                for (int i=providers.size()-1; i>=0; i--) {
8571                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8572                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8573                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8574                                + ": not system .apk");
8575                        providers.remove(i);
8576                    }
8577                }
8578            }
8579        }
8580        if (providers != null) {
8581            mSystemThread.installSystemProviders(providers);
8582        }
8583
8584        mCoreSettingsObserver = new CoreSettingsObserver(this);
8585
8586        mUsageStatsService.monitorPackages();
8587    }
8588
8589    /**
8590     * Allows app to retrieve the MIME type of a URI without having permission
8591     * to access its content provider.
8592     *
8593     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8594     *
8595     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8596     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8597     */
8598    public String getProviderMimeType(Uri uri, int userId) {
8599        enforceNotIsolatedCaller("getProviderMimeType");
8600        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8601                userId, false, true, "getProviderMimeType", null);
8602        final String name = uri.getAuthority();
8603        final long ident = Binder.clearCallingIdentity();
8604        ContentProviderHolder holder = null;
8605
8606        try {
8607            holder = getContentProviderExternalUnchecked(name, null, userId);
8608            if (holder != null) {
8609                return holder.provider.getType(uri);
8610            }
8611        } catch (RemoteException e) {
8612            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8613            return null;
8614        } finally {
8615            if (holder != null) {
8616                removeContentProviderExternalUnchecked(name, null, userId);
8617            }
8618            Binder.restoreCallingIdentity(ident);
8619        }
8620
8621        return null;
8622    }
8623
8624    // =========================================================
8625    // GLOBAL MANAGEMENT
8626    // =========================================================
8627
8628    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8629            boolean isolated) {
8630        String proc = customProcess != null ? customProcess : info.processName;
8631        BatteryStatsImpl.Uid.Proc ps = null;
8632        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8633        int uid = info.uid;
8634        if (isolated) {
8635            int userId = UserHandle.getUserId(uid);
8636            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8637            while (true) {
8638                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8639                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8640                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8641                }
8642                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8643                mNextIsolatedProcessUid++;
8644                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8645                    // No process for this uid, use it.
8646                    break;
8647                }
8648                stepsLeft--;
8649                if (stepsLeft <= 0) {
8650                    return null;
8651                }
8652            }
8653        }
8654        return new ProcessRecord(stats, info, proc, uid);
8655    }
8656
8657    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8658            String abiOverride) {
8659        ProcessRecord app;
8660        if (!isolated) {
8661            app = getProcessRecordLocked(info.processName, info.uid, true);
8662        } else {
8663            app = null;
8664        }
8665
8666        if (app == null) {
8667            app = newProcessRecordLocked(info, null, isolated);
8668            mProcessNames.put(info.processName, app.uid, app);
8669            if (isolated) {
8670                mIsolatedProcesses.put(app.uid, app);
8671            }
8672            updateLruProcessLocked(app, false, null);
8673            updateOomAdjLocked();
8674        }
8675
8676        // This package really, really can not be stopped.
8677        try {
8678            AppGlobals.getPackageManager().setPackageStoppedState(
8679                    info.packageName, false, UserHandle.getUserId(app.uid));
8680        } catch (RemoteException e) {
8681        } catch (IllegalArgumentException e) {
8682            Slog.w(TAG, "Failed trying to unstop package "
8683                    + info.packageName + ": " + e);
8684        }
8685
8686        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8687                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8688            app.persistent = true;
8689            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8690        }
8691        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8692            mPersistentStartingProcesses.add(app);
8693            startProcessLocked(app, "added application", app.processName,
8694                    abiOverride);
8695        }
8696
8697        return app;
8698    }
8699
8700    public void unhandledBack() {
8701        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8702                "unhandledBack()");
8703
8704        synchronized(this) {
8705            final long origId = Binder.clearCallingIdentity();
8706            try {
8707                getFocusedStack().unhandledBackLocked();
8708            } finally {
8709                Binder.restoreCallingIdentity(origId);
8710            }
8711        }
8712    }
8713
8714    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8715        enforceNotIsolatedCaller("openContentUri");
8716        final int userId = UserHandle.getCallingUserId();
8717        String name = uri.getAuthority();
8718        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8719        ParcelFileDescriptor pfd = null;
8720        if (cph != null) {
8721            // We record the binder invoker's uid in thread-local storage before
8722            // going to the content provider to open the file.  Later, in the code
8723            // that handles all permissions checks, we look for this uid and use
8724            // that rather than the Activity Manager's own uid.  The effect is that
8725            // we do the check against the caller's permissions even though it looks
8726            // to the content provider like the Activity Manager itself is making
8727            // the request.
8728            sCallerIdentity.set(new Identity(
8729                    Binder.getCallingPid(), Binder.getCallingUid()));
8730            try {
8731                pfd = cph.provider.openFile(null, uri, "r", null);
8732            } catch (FileNotFoundException e) {
8733                // do nothing; pfd will be returned null
8734            } finally {
8735                // Ensure that whatever happens, we clean up the identity state
8736                sCallerIdentity.remove();
8737            }
8738
8739            // We've got the fd now, so we're done with the provider.
8740            removeContentProviderExternalUnchecked(name, null, userId);
8741        } else {
8742            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8743        }
8744        return pfd;
8745    }
8746
8747    // Actually is sleeping or shutting down or whatever else in the future
8748    // is an inactive state.
8749    public boolean isSleepingOrShuttingDown() {
8750        return mSleeping || mShuttingDown;
8751    }
8752
8753    public boolean isSleeping() {
8754        return mSleeping;
8755    }
8756
8757    void goingToSleep() {
8758        synchronized(this) {
8759            mWentToSleep = true;
8760            updateEventDispatchingLocked();
8761            goToSleepIfNeededLocked();
8762        }
8763    }
8764
8765    void finishRunningVoiceLocked() {
8766        if (mRunningVoice) {
8767            mRunningVoice = false;
8768            goToSleepIfNeededLocked();
8769        }
8770    }
8771
8772    void goToSleepIfNeededLocked() {
8773        if (mWentToSleep && !mRunningVoice) {
8774            if (!mSleeping) {
8775                mSleeping = true;
8776                mStackSupervisor.goingToSleepLocked();
8777
8778                // Initialize the wake times of all processes.
8779                checkExcessivePowerUsageLocked(false);
8780                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8781                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8782                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8783            }
8784        }
8785    }
8786
8787    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8788        mTaskPersister.notify(task, flush);
8789    }
8790
8791    @Override
8792    public boolean shutdown(int timeout) {
8793        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8794                != PackageManager.PERMISSION_GRANTED) {
8795            throw new SecurityException("Requires permission "
8796                    + android.Manifest.permission.SHUTDOWN);
8797        }
8798
8799        boolean timedout = false;
8800
8801        synchronized(this) {
8802            mShuttingDown = true;
8803            updateEventDispatchingLocked();
8804            timedout = mStackSupervisor.shutdownLocked(timeout);
8805        }
8806
8807        mAppOpsService.shutdown();
8808        mUsageStatsService.shutdown();
8809        mBatteryStatsService.shutdown();
8810        synchronized (this) {
8811            mProcessStats.shutdownLocked();
8812        }
8813        notifyTaskPersisterLocked(null, true);
8814
8815        return timedout;
8816    }
8817
8818    public final void activitySlept(IBinder token) {
8819        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8820
8821        final long origId = Binder.clearCallingIdentity();
8822
8823        synchronized (this) {
8824            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8825            if (r != null) {
8826                mStackSupervisor.activitySleptLocked(r);
8827            }
8828        }
8829
8830        Binder.restoreCallingIdentity(origId);
8831    }
8832
8833    void logLockScreen(String msg) {
8834        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8835                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8836                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8837                mStackSupervisor.mDismissKeyguardOnNextActivity);
8838    }
8839
8840    private void comeOutOfSleepIfNeededLocked() {
8841        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8842            if (mSleeping) {
8843                mSleeping = false;
8844                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8845            }
8846        }
8847    }
8848
8849    void wakingUp() {
8850        synchronized(this) {
8851            mWentToSleep = false;
8852            updateEventDispatchingLocked();
8853            comeOutOfSleepIfNeededLocked();
8854        }
8855    }
8856
8857    void startRunningVoiceLocked() {
8858        if (!mRunningVoice) {
8859            mRunningVoice = true;
8860            comeOutOfSleepIfNeededLocked();
8861        }
8862    }
8863
8864    private void updateEventDispatchingLocked() {
8865        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8866    }
8867
8868    public void setLockScreenShown(boolean shown) {
8869        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8870                != PackageManager.PERMISSION_GRANTED) {
8871            throw new SecurityException("Requires permission "
8872                    + android.Manifest.permission.DEVICE_POWER);
8873        }
8874
8875        synchronized(this) {
8876            long ident = Binder.clearCallingIdentity();
8877            try {
8878                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8879                mLockScreenShown = shown;
8880                comeOutOfSleepIfNeededLocked();
8881            } finally {
8882                Binder.restoreCallingIdentity(ident);
8883            }
8884        }
8885    }
8886
8887    public void stopAppSwitches() {
8888        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8889                != PackageManager.PERMISSION_GRANTED) {
8890            throw new SecurityException("Requires permission "
8891                    + android.Manifest.permission.STOP_APP_SWITCHES);
8892        }
8893
8894        synchronized(this) {
8895            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8896                    + APP_SWITCH_DELAY_TIME;
8897            mDidAppSwitch = false;
8898            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8899            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8900            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8901        }
8902    }
8903
8904    public void resumeAppSwitches() {
8905        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8906                != PackageManager.PERMISSION_GRANTED) {
8907            throw new SecurityException("Requires permission "
8908                    + android.Manifest.permission.STOP_APP_SWITCHES);
8909        }
8910
8911        synchronized(this) {
8912            // Note that we don't execute any pending app switches... we will
8913            // let those wait until either the timeout, or the next start
8914            // activity request.
8915            mAppSwitchesAllowedTime = 0;
8916        }
8917    }
8918
8919    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8920            String name) {
8921        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8922            return true;
8923        }
8924
8925        final int perm = checkComponentPermission(
8926                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8927                callingUid, -1, true);
8928        if (perm == PackageManager.PERMISSION_GRANTED) {
8929            return true;
8930        }
8931
8932        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8933        return false;
8934    }
8935
8936    public void setDebugApp(String packageName, boolean waitForDebugger,
8937            boolean persistent) {
8938        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8939                "setDebugApp()");
8940
8941        long ident = Binder.clearCallingIdentity();
8942        try {
8943            // Note that this is not really thread safe if there are multiple
8944            // callers into it at the same time, but that's not a situation we
8945            // care about.
8946            if (persistent) {
8947                final ContentResolver resolver = mContext.getContentResolver();
8948                Settings.Global.putString(
8949                    resolver, Settings.Global.DEBUG_APP,
8950                    packageName);
8951                Settings.Global.putInt(
8952                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8953                    waitForDebugger ? 1 : 0);
8954            }
8955
8956            synchronized (this) {
8957                if (!persistent) {
8958                    mOrigDebugApp = mDebugApp;
8959                    mOrigWaitForDebugger = mWaitForDebugger;
8960                }
8961                mDebugApp = packageName;
8962                mWaitForDebugger = waitForDebugger;
8963                mDebugTransient = !persistent;
8964                if (packageName != null) {
8965                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8966                            false, UserHandle.USER_ALL, "set debug app");
8967                }
8968            }
8969        } finally {
8970            Binder.restoreCallingIdentity(ident);
8971        }
8972    }
8973
8974    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8975        synchronized (this) {
8976            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8977            if (!isDebuggable) {
8978                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8979                    throw new SecurityException("Process not debuggable: " + app.packageName);
8980                }
8981            }
8982
8983            mOpenGlTraceApp = processName;
8984        }
8985    }
8986
8987    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8988            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8989        synchronized (this) {
8990            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8991            if (!isDebuggable) {
8992                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8993                    throw new SecurityException("Process not debuggable: " + app.packageName);
8994                }
8995            }
8996            mProfileApp = processName;
8997            mProfileFile = profileFile;
8998            if (mProfileFd != null) {
8999                try {
9000                    mProfileFd.close();
9001                } catch (IOException e) {
9002                }
9003                mProfileFd = null;
9004            }
9005            mProfileFd = profileFd;
9006            mProfileType = 0;
9007            mAutoStopProfiler = autoStopProfiler;
9008        }
9009    }
9010
9011    @Override
9012    public void setAlwaysFinish(boolean enabled) {
9013        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9014                "setAlwaysFinish()");
9015
9016        Settings.Global.putInt(
9017                mContext.getContentResolver(),
9018                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9019
9020        synchronized (this) {
9021            mAlwaysFinishActivities = enabled;
9022        }
9023    }
9024
9025    @Override
9026    public void setActivityController(IActivityController controller) {
9027        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9028                "setActivityController()");
9029        synchronized (this) {
9030            mController = controller;
9031            Watchdog.getInstance().setActivityController(controller);
9032        }
9033    }
9034
9035    @Override
9036    public void setUserIsMonkey(boolean userIsMonkey) {
9037        synchronized (this) {
9038            synchronized (mPidsSelfLocked) {
9039                final int callingPid = Binder.getCallingPid();
9040                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9041                if (precessRecord == null) {
9042                    throw new SecurityException("Unknown process: " + callingPid);
9043                }
9044                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9045                    throw new SecurityException("Only an instrumentation process "
9046                            + "with a UiAutomation can call setUserIsMonkey");
9047                }
9048            }
9049            mUserIsMonkey = userIsMonkey;
9050        }
9051    }
9052
9053    @Override
9054    public boolean isUserAMonkey() {
9055        synchronized (this) {
9056            // If there is a controller also implies the user is a monkey.
9057            return (mUserIsMonkey || mController != null);
9058        }
9059    }
9060
9061    public void requestBugReport() {
9062        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9063        SystemProperties.set("ctl.start", "bugreport");
9064    }
9065
9066    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9067        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9068    }
9069
9070    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9071        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9072            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9073        }
9074        return KEY_DISPATCHING_TIMEOUT;
9075    }
9076
9077    @Override
9078    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9079        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9080                != PackageManager.PERMISSION_GRANTED) {
9081            throw new SecurityException("Requires permission "
9082                    + android.Manifest.permission.FILTER_EVENTS);
9083        }
9084        ProcessRecord proc;
9085        long timeout;
9086        synchronized (this) {
9087            synchronized (mPidsSelfLocked) {
9088                proc = mPidsSelfLocked.get(pid);
9089            }
9090            timeout = getInputDispatchingTimeoutLocked(proc);
9091        }
9092
9093        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9094            return -1;
9095        }
9096
9097        return timeout;
9098    }
9099
9100    /**
9101     * Handle input dispatching timeouts.
9102     * Returns whether input dispatching should be aborted or not.
9103     */
9104    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9105            final ActivityRecord activity, final ActivityRecord parent,
9106            final boolean aboveSystem, String reason) {
9107        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9108                != PackageManager.PERMISSION_GRANTED) {
9109            throw new SecurityException("Requires permission "
9110                    + android.Manifest.permission.FILTER_EVENTS);
9111        }
9112
9113        final String annotation;
9114        if (reason == null) {
9115            annotation = "Input dispatching timed out";
9116        } else {
9117            annotation = "Input dispatching timed out (" + reason + ")";
9118        }
9119
9120        if (proc != null) {
9121            synchronized (this) {
9122                if (proc.debugging) {
9123                    return false;
9124                }
9125
9126                if (mDidDexOpt) {
9127                    // Give more time since we were dexopting.
9128                    mDidDexOpt = false;
9129                    return false;
9130                }
9131
9132                if (proc.instrumentationClass != null) {
9133                    Bundle info = new Bundle();
9134                    info.putString("shortMsg", "keyDispatchingTimedOut");
9135                    info.putString("longMsg", annotation);
9136                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9137                    return true;
9138                }
9139            }
9140            mHandler.post(new Runnable() {
9141                @Override
9142                public void run() {
9143                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9144                }
9145            });
9146        }
9147
9148        return true;
9149    }
9150
9151    public Bundle getAssistContextExtras(int requestType) {
9152        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9153                "getAssistContextExtras()");
9154        PendingAssistExtras pae;
9155        Bundle extras = new Bundle();
9156        synchronized (this) {
9157            ActivityRecord activity = getFocusedStack().mResumedActivity;
9158            if (activity == null) {
9159                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9160                return null;
9161            }
9162            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9163            if (activity.app == null || activity.app.thread == null) {
9164                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9165                return extras;
9166            }
9167            if (activity.app.pid == Binder.getCallingPid()) {
9168                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9169                return extras;
9170            }
9171            pae = new PendingAssistExtras(activity);
9172            try {
9173                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9174                        requestType);
9175                mPendingAssistExtras.add(pae);
9176                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9177            } catch (RemoteException e) {
9178                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9179                return extras;
9180            }
9181        }
9182        synchronized (pae) {
9183            while (!pae.haveResult) {
9184                try {
9185                    pae.wait();
9186                } catch (InterruptedException e) {
9187                }
9188            }
9189            if (pae.result != null) {
9190                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9191            }
9192        }
9193        synchronized (this) {
9194            mPendingAssistExtras.remove(pae);
9195            mHandler.removeCallbacks(pae);
9196        }
9197        return extras;
9198    }
9199
9200    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9201        PendingAssistExtras pae = (PendingAssistExtras)token;
9202        synchronized (pae) {
9203            pae.result = extras;
9204            pae.haveResult = true;
9205            pae.notifyAll();
9206        }
9207    }
9208
9209    public void registerProcessObserver(IProcessObserver observer) {
9210        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9211                "registerProcessObserver()");
9212        synchronized (this) {
9213            mProcessObservers.register(observer);
9214        }
9215    }
9216
9217    @Override
9218    public void unregisterProcessObserver(IProcessObserver observer) {
9219        synchronized (this) {
9220            mProcessObservers.unregister(observer);
9221        }
9222    }
9223
9224    @Override
9225    public boolean convertFromTranslucent(IBinder token) {
9226        final long origId = Binder.clearCallingIdentity();
9227        try {
9228            synchronized (this) {
9229                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9230                if (r == null) {
9231                    return false;
9232                }
9233                if (r.changeWindowTranslucency(true)) {
9234                    mWindowManager.setAppFullscreen(token, true);
9235                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9236                    return true;
9237                }
9238                return false;
9239            }
9240        } finally {
9241            Binder.restoreCallingIdentity(origId);
9242        }
9243    }
9244
9245    @Override
9246    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9247        final long origId = Binder.clearCallingIdentity();
9248        try {
9249            synchronized (this) {
9250                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9251                if (r == null) {
9252                    return false;
9253                }
9254                if (r.changeWindowTranslucency(false)) {
9255                    r.task.stack.convertToTranslucent(r, options);
9256                    mWindowManager.setAppFullscreen(token, false);
9257                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9258                    return true;
9259                }
9260                return false;
9261            }
9262        } finally {
9263            Binder.restoreCallingIdentity(origId);
9264        }
9265    }
9266
9267    @Override
9268    public ActivityOptions getActivityOptions(IBinder token) {
9269        final long origId = Binder.clearCallingIdentity();
9270        try {
9271            synchronized (this) {
9272                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9273                if (r != null) {
9274                    final ActivityOptions activityOptions = r.pendingOptions;
9275                    r.pendingOptions = null;
9276                    return activityOptions;
9277                }
9278                return null;
9279            }
9280        } finally {
9281            Binder.restoreCallingIdentity(origId);
9282        }
9283    }
9284
9285    @Override
9286    public void setImmersive(IBinder token, boolean immersive) {
9287        synchronized(this) {
9288            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9289            if (r == null) {
9290                throw new IllegalArgumentException();
9291            }
9292            r.immersive = immersive;
9293
9294            // update associated state if we're frontmost
9295            if (r == mFocusedActivity) {
9296                if (DEBUG_IMMERSIVE) {
9297                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9298                }
9299                applyUpdateLockStateLocked(r);
9300            }
9301        }
9302    }
9303
9304    @Override
9305    public boolean isImmersive(IBinder token) {
9306        synchronized (this) {
9307            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9308            if (r == null) {
9309                throw new IllegalArgumentException();
9310            }
9311            return r.immersive;
9312        }
9313    }
9314
9315    public boolean isTopActivityImmersive() {
9316        enforceNotIsolatedCaller("startActivity");
9317        synchronized (this) {
9318            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9319            return (r != null) ? r.immersive : false;
9320        }
9321    }
9322
9323    public final void enterSafeMode() {
9324        synchronized(this) {
9325            // It only makes sense to do this before the system is ready
9326            // and started launching other packages.
9327            if (!mSystemReady) {
9328                try {
9329                    AppGlobals.getPackageManager().enterSafeMode();
9330                } catch (RemoteException e) {
9331                }
9332            }
9333
9334            mSafeMode = true;
9335        }
9336    }
9337
9338    public final void showSafeModeOverlay() {
9339        View v = LayoutInflater.from(mContext).inflate(
9340                com.android.internal.R.layout.safe_mode, null);
9341        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9342        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9343        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9344        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9345        lp.gravity = Gravity.BOTTOM | Gravity.START;
9346        lp.format = v.getBackground().getOpacity();
9347        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9348                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9349        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9350        ((WindowManager)mContext.getSystemService(
9351                Context.WINDOW_SERVICE)).addView(v, lp);
9352    }
9353
9354    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9355        if (!(sender instanceof PendingIntentRecord)) {
9356            return;
9357        }
9358        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9359        synchronized (stats) {
9360            if (mBatteryStatsService.isOnBattery()) {
9361                mBatteryStatsService.enforceCallingPermission();
9362                PendingIntentRecord rec = (PendingIntentRecord)sender;
9363                int MY_UID = Binder.getCallingUid();
9364                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9365                BatteryStatsImpl.Uid.Pkg pkg =
9366                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9367                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9368                pkg.incWakeupsLocked();
9369            }
9370        }
9371    }
9372
9373    public boolean killPids(int[] pids, String pReason, boolean secure) {
9374        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9375            throw new SecurityException("killPids only available to the system");
9376        }
9377        String reason = (pReason == null) ? "Unknown" : pReason;
9378        // XXX Note: don't acquire main activity lock here, because the window
9379        // manager calls in with its locks held.
9380
9381        boolean killed = false;
9382        synchronized (mPidsSelfLocked) {
9383            int[] types = new int[pids.length];
9384            int worstType = 0;
9385            for (int i=0; i<pids.length; i++) {
9386                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9387                if (proc != null) {
9388                    int type = proc.setAdj;
9389                    types[i] = type;
9390                    if (type > worstType) {
9391                        worstType = type;
9392                    }
9393                }
9394            }
9395
9396            // If the worst oom_adj is somewhere in the cached proc LRU range,
9397            // then constrain it so we will kill all cached procs.
9398            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9399                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9400                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9401            }
9402
9403            // If this is not a secure call, don't let it kill processes that
9404            // are important.
9405            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9406                worstType = ProcessList.SERVICE_ADJ;
9407            }
9408
9409            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9410            for (int i=0; i<pids.length; i++) {
9411                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9412                if (proc == null) {
9413                    continue;
9414                }
9415                int adj = proc.setAdj;
9416                if (adj >= worstType && !proc.killedByAm) {
9417                    killUnneededProcessLocked(proc, reason);
9418                    killed = true;
9419                }
9420            }
9421        }
9422        return killed;
9423    }
9424
9425    @Override
9426    public void killUid(int uid, String reason) {
9427        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9428            throw new SecurityException("killUid only available to the system");
9429        }
9430        synchronized (this) {
9431            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9432                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9433                    reason != null ? reason : "kill uid");
9434        }
9435    }
9436
9437    @Override
9438    public boolean killProcessesBelowForeground(String reason) {
9439        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9440            throw new SecurityException("killProcessesBelowForeground() only available to system");
9441        }
9442
9443        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9444    }
9445
9446    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9447        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9448            throw new SecurityException("killProcessesBelowAdj() only available to system");
9449        }
9450
9451        boolean killed = false;
9452        synchronized (mPidsSelfLocked) {
9453            final int size = mPidsSelfLocked.size();
9454            for (int i = 0; i < size; i++) {
9455                final int pid = mPidsSelfLocked.keyAt(i);
9456                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9457                if (proc == null) continue;
9458
9459                final int adj = proc.setAdj;
9460                if (adj > belowAdj && !proc.killedByAm) {
9461                    killUnneededProcessLocked(proc, reason);
9462                    killed = true;
9463                }
9464            }
9465        }
9466        return killed;
9467    }
9468
9469    @Override
9470    public void hang(final IBinder who, boolean allowRestart) {
9471        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9472                != PackageManager.PERMISSION_GRANTED) {
9473            throw new SecurityException("Requires permission "
9474                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9475        }
9476
9477        final IBinder.DeathRecipient death = new DeathRecipient() {
9478            @Override
9479            public void binderDied() {
9480                synchronized (this) {
9481                    notifyAll();
9482                }
9483            }
9484        };
9485
9486        try {
9487            who.linkToDeath(death, 0);
9488        } catch (RemoteException e) {
9489            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9490            return;
9491        }
9492
9493        synchronized (this) {
9494            Watchdog.getInstance().setAllowRestart(allowRestart);
9495            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9496            synchronized (death) {
9497                while (who.isBinderAlive()) {
9498                    try {
9499                        death.wait();
9500                    } catch (InterruptedException e) {
9501                    }
9502                }
9503            }
9504            Watchdog.getInstance().setAllowRestart(true);
9505        }
9506    }
9507
9508    @Override
9509    public void restart() {
9510        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9511                != PackageManager.PERMISSION_GRANTED) {
9512            throw new SecurityException("Requires permission "
9513                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9514        }
9515
9516        Log.i(TAG, "Sending shutdown broadcast...");
9517
9518        BroadcastReceiver br = new BroadcastReceiver() {
9519            @Override public void onReceive(Context context, Intent intent) {
9520                // Now the broadcast is done, finish up the low-level shutdown.
9521                Log.i(TAG, "Shutting down activity manager...");
9522                shutdown(10000);
9523                Log.i(TAG, "Shutdown complete, restarting!");
9524                Process.killProcess(Process.myPid());
9525                System.exit(10);
9526            }
9527        };
9528
9529        // First send the high-level shut down broadcast.
9530        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9531        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9532        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9533        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9534        mContext.sendOrderedBroadcastAsUser(intent,
9535                UserHandle.ALL, null, br, mHandler, 0, null, null);
9536        */
9537        br.onReceive(mContext, intent);
9538    }
9539
9540    private long getLowRamTimeSinceIdle(long now) {
9541        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9542    }
9543
9544    @Override
9545    public void performIdleMaintenance() {
9546        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9547                != PackageManager.PERMISSION_GRANTED) {
9548            throw new SecurityException("Requires permission "
9549                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9550        }
9551
9552        synchronized (this) {
9553            final long now = SystemClock.uptimeMillis();
9554            final long timeSinceLastIdle = now - mLastIdleTime;
9555            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9556            mLastIdleTime = now;
9557            mLowRamTimeSinceLastIdle = 0;
9558            if (mLowRamStartTime != 0) {
9559                mLowRamStartTime = now;
9560            }
9561
9562            StringBuilder sb = new StringBuilder(128);
9563            sb.append("Idle maintenance over ");
9564            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9565            sb.append(" low RAM for ");
9566            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9567            Slog.i(TAG, sb.toString());
9568
9569            // If at least 1/3 of our time since the last idle period has been spent
9570            // with RAM low, then we want to kill processes.
9571            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9572
9573            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9574                ProcessRecord proc = mLruProcesses.get(i);
9575                if (proc.notCachedSinceIdle) {
9576                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9577                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9578                        if (doKilling && proc.initialIdlePss != 0
9579                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9580                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9581                                    + " from " + proc.initialIdlePss + ")");
9582                        }
9583                    }
9584                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9585                    proc.notCachedSinceIdle = true;
9586                    proc.initialIdlePss = 0;
9587                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9588                            isSleeping(), now);
9589                }
9590            }
9591
9592            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9593            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9594        }
9595    }
9596
9597    private void retrieveSettings() {
9598        final ContentResolver resolver = mContext.getContentResolver();
9599        String debugApp = Settings.Global.getString(
9600            resolver, Settings.Global.DEBUG_APP);
9601        boolean waitForDebugger = Settings.Global.getInt(
9602            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9603        boolean alwaysFinishActivities = Settings.Global.getInt(
9604            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9605        boolean forceRtl = Settings.Global.getInt(
9606                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9607        // Transfer any global setting for forcing RTL layout, into a System Property
9608        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9609
9610        Configuration configuration = new Configuration();
9611        Settings.System.getConfiguration(resolver, configuration);
9612        if (forceRtl) {
9613            // This will take care of setting the correct layout direction flags
9614            configuration.setLayoutDirection(configuration.locale);
9615        }
9616
9617        synchronized (this) {
9618            mDebugApp = mOrigDebugApp = debugApp;
9619            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9620            mAlwaysFinishActivities = alwaysFinishActivities;
9621            // This happens before any activities are started, so we can
9622            // change mConfiguration in-place.
9623            updateConfigurationLocked(configuration, null, false, true);
9624            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9625        }
9626    }
9627
9628    public boolean testIsSystemReady() {
9629        // no need to synchronize(this) just to read & return the value
9630        return mSystemReady;
9631    }
9632
9633    private static File getCalledPreBootReceiversFile() {
9634        File dataDir = Environment.getDataDirectory();
9635        File systemDir = new File(dataDir, "system");
9636        File fname = new File(systemDir, "called_pre_boots.dat");
9637        return fname;
9638    }
9639
9640    static final int LAST_DONE_VERSION = 10000;
9641
9642    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9643        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9644        File file = getCalledPreBootReceiversFile();
9645        FileInputStream fis = null;
9646        try {
9647            fis = new FileInputStream(file);
9648            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9649            int fvers = dis.readInt();
9650            if (fvers == LAST_DONE_VERSION) {
9651                String vers = dis.readUTF();
9652                String codename = dis.readUTF();
9653                String build = dis.readUTF();
9654                if (android.os.Build.VERSION.RELEASE.equals(vers)
9655                        && android.os.Build.VERSION.CODENAME.equals(codename)
9656                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9657                    int num = dis.readInt();
9658                    while (num > 0) {
9659                        num--;
9660                        String pkg = dis.readUTF();
9661                        String cls = dis.readUTF();
9662                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9663                    }
9664                }
9665            }
9666        } catch (FileNotFoundException e) {
9667        } catch (IOException e) {
9668            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9669        } finally {
9670            if (fis != null) {
9671                try {
9672                    fis.close();
9673                } catch (IOException e) {
9674                }
9675            }
9676        }
9677        return lastDoneReceivers;
9678    }
9679
9680    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9681        File file = getCalledPreBootReceiversFile();
9682        FileOutputStream fos = null;
9683        DataOutputStream dos = null;
9684        try {
9685            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9686            fos = new FileOutputStream(file);
9687            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9688            dos.writeInt(LAST_DONE_VERSION);
9689            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9690            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9691            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9692            dos.writeInt(list.size());
9693            for (int i=0; i<list.size(); i++) {
9694                dos.writeUTF(list.get(i).getPackageName());
9695                dos.writeUTF(list.get(i).getClassName());
9696            }
9697        } catch (IOException e) {
9698            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9699            file.delete();
9700        } finally {
9701            FileUtils.sync(fos);
9702            if (dos != null) {
9703                try {
9704                    dos.close();
9705                } catch (IOException e) {
9706                    // TODO Auto-generated catch block
9707                    e.printStackTrace();
9708                }
9709            }
9710        }
9711    }
9712
9713    public void systemReady(final Runnable goingCallback) {
9714        synchronized(this) {
9715            if (mSystemReady) {
9716                if (goingCallback != null) goingCallback.run();
9717                return;
9718            }
9719
9720            if (mRecentTasks == null) {
9721                mRecentTasks = mTaskPersister.restoreTasksLocked();
9722                if (!mRecentTasks.isEmpty()) {
9723                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9724                }
9725                mTaskPersister.startPersisting();
9726            }
9727
9728            // Check to see if there are any update receivers to run.
9729            if (!mDidUpdate) {
9730                if (mWaitingUpdate) {
9731                    return;
9732                }
9733                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9734                List<ResolveInfo> ris = null;
9735                try {
9736                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9737                            intent, null, 0, 0);
9738                } catch (RemoteException e) {
9739                }
9740                if (ris != null) {
9741                    for (int i=ris.size()-1; i>=0; i--) {
9742                        if ((ris.get(i).activityInfo.applicationInfo.flags
9743                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9744                            ris.remove(i);
9745                        }
9746                    }
9747                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9748
9749                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9750
9751                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9752                    for (int i=0; i<ris.size(); i++) {
9753                        ActivityInfo ai = ris.get(i).activityInfo;
9754                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9755                        if (lastDoneReceivers.contains(comp)) {
9756                            // We already did the pre boot receiver for this app with the current
9757                            // platform version, so don't do it again...
9758                            ris.remove(i);
9759                            i--;
9760                            // ...however, do keep it as one that has been done, so we don't
9761                            // forget about it when rewriting the file of last done receivers.
9762                            doneReceivers.add(comp);
9763                        }
9764                    }
9765
9766                    final int[] users = getUsersLocked();
9767                    for (int i=0; i<ris.size(); i++) {
9768                        ActivityInfo ai = ris.get(i).activityInfo;
9769                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9770                        doneReceivers.add(comp);
9771                        intent.setComponent(comp);
9772                        for (int j=0; j<users.length; j++) {
9773                            IIntentReceiver finisher = null;
9774                            if (i == ris.size()-1 && j == users.length-1) {
9775                                finisher = new IIntentReceiver.Stub() {
9776                                    public void performReceive(Intent intent, int resultCode,
9777                                            String data, Bundle extras, boolean ordered,
9778                                            boolean sticky, int sendingUser) {
9779                                        // The raw IIntentReceiver interface is called
9780                                        // with the AM lock held, so redispatch to
9781                                        // execute our code without the lock.
9782                                        mHandler.post(new Runnable() {
9783                                            public void run() {
9784                                                synchronized (ActivityManagerService.this) {
9785                                                    mDidUpdate = true;
9786                                                }
9787                                                writeLastDonePreBootReceivers(doneReceivers);
9788                                                showBootMessage(mContext.getText(
9789                                                        R.string.android_upgrading_complete),
9790                                                        false);
9791                                                systemReady(goingCallback);
9792                                            }
9793                                        });
9794                                    }
9795                                };
9796                            }
9797                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9798                                    + " for user " + users[j]);
9799                            broadcastIntentLocked(null, null, intent, null, finisher,
9800                                    0, null, null, null, AppOpsManager.OP_NONE,
9801                                    true, false, MY_PID, Process.SYSTEM_UID,
9802                                    users[j]);
9803                            if (finisher != null) {
9804                                mWaitingUpdate = true;
9805                            }
9806                        }
9807                    }
9808                }
9809                if (mWaitingUpdate) {
9810                    return;
9811                }
9812                mDidUpdate = true;
9813            }
9814
9815            mAppOpsService.systemReady();
9816            mUsageStatsService.systemReady();
9817            mSystemReady = true;
9818        }
9819
9820        ArrayList<ProcessRecord> procsToKill = null;
9821        synchronized(mPidsSelfLocked) {
9822            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9823                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9824                if (!isAllowedWhileBooting(proc.info)){
9825                    if (procsToKill == null) {
9826                        procsToKill = new ArrayList<ProcessRecord>();
9827                    }
9828                    procsToKill.add(proc);
9829                }
9830            }
9831        }
9832
9833        synchronized(this) {
9834            if (procsToKill != null) {
9835                for (int i=procsToKill.size()-1; i>=0; i--) {
9836                    ProcessRecord proc = procsToKill.get(i);
9837                    Slog.i(TAG, "Removing system update proc: " + proc);
9838                    removeProcessLocked(proc, true, false, "system update done");
9839                }
9840            }
9841
9842            // Now that we have cleaned up any update processes, we
9843            // are ready to start launching real processes and know that
9844            // we won't trample on them any more.
9845            mProcessesReady = true;
9846        }
9847
9848        Slog.i(TAG, "System now ready");
9849        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9850            SystemClock.uptimeMillis());
9851
9852        synchronized(this) {
9853            // Make sure we have no pre-ready processes sitting around.
9854
9855            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9856                ResolveInfo ri = mContext.getPackageManager()
9857                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9858                                STOCK_PM_FLAGS);
9859                CharSequence errorMsg = null;
9860                if (ri != null) {
9861                    ActivityInfo ai = ri.activityInfo;
9862                    ApplicationInfo app = ai.applicationInfo;
9863                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9864                        mTopAction = Intent.ACTION_FACTORY_TEST;
9865                        mTopData = null;
9866                        mTopComponent = new ComponentName(app.packageName,
9867                                ai.name);
9868                    } else {
9869                        errorMsg = mContext.getResources().getText(
9870                                com.android.internal.R.string.factorytest_not_system);
9871                    }
9872                } else {
9873                    errorMsg = mContext.getResources().getText(
9874                            com.android.internal.R.string.factorytest_no_action);
9875                }
9876                if (errorMsg != null) {
9877                    mTopAction = null;
9878                    mTopData = null;
9879                    mTopComponent = null;
9880                    Message msg = Message.obtain();
9881                    msg.what = SHOW_FACTORY_ERROR_MSG;
9882                    msg.getData().putCharSequence("msg", errorMsg);
9883                    mHandler.sendMessage(msg);
9884                }
9885            }
9886        }
9887
9888        retrieveSettings();
9889
9890        synchronized (this) {
9891            readGrantedUriPermissionsLocked();
9892        }
9893
9894        if (goingCallback != null) goingCallback.run();
9895
9896        mSystemServiceManager.startUser(mCurrentUserId);
9897
9898        synchronized (this) {
9899            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9900                try {
9901                    List apps = AppGlobals.getPackageManager().
9902                        getPersistentApplications(STOCK_PM_FLAGS);
9903                    if (apps != null) {
9904                        int N = apps.size();
9905                        int i;
9906                        for (i=0; i<N; i++) {
9907                            ApplicationInfo info
9908                                = (ApplicationInfo)apps.get(i);
9909                            if (info != null &&
9910                                    !info.packageName.equals("android")) {
9911                                addAppLocked(info, false, null /* ABI override */);
9912                            }
9913                        }
9914                    }
9915                } catch (RemoteException ex) {
9916                    // pm is in same process, this will never happen.
9917                }
9918            }
9919
9920            // Start up initial activity.
9921            mBooting = true;
9922
9923            try {
9924                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9925                    Message msg = Message.obtain();
9926                    msg.what = SHOW_UID_ERROR_MSG;
9927                    mHandler.sendMessage(msg);
9928                }
9929            } catch (RemoteException e) {
9930            }
9931
9932            long ident = Binder.clearCallingIdentity();
9933            try {
9934                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9935                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9936                        | Intent.FLAG_RECEIVER_FOREGROUND);
9937                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9938                broadcastIntentLocked(null, null, intent,
9939                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9940                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9941                intent = new Intent(Intent.ACTION_USER_STARTING);
9942                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9943                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9944                broadcastIntentLocked(null, null, intent,
9945                        null, new IIntentReceiver.Stub() {
9946                            @Override
9947                            public void performReceive(Intent intent, int resultCode, String data,
9948                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9949                                    throws RemoteException {
9950                            }
9951                        }, 0, null, null,
9952                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9953                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9954            } catch (Throwable t) {
9955                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9956            } finally {
9957                Binder.restoreCallingIdentity(ident);
9958            }
9959            mStackSupervisor.resumeTopActivitiesLocked();
9960            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9961        }
9962    }
9963
9964    private boolean makeAppCrashingLocked(ProcessRecord app,
9965            String shortMsg, String longMsg, String stackTrace) {
9966        app.crashing = true;
9967        app.crashingReport = generateProcessError(app,
9968                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9969        startAppProblemLocked(app);
9970        app.stopFreezingAllLocked();
9971        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9972    }
9973
9974    private void makeAppNotRespondingLocked(ProcessRecord app,
9975            String activity, String shortMsg, String longMsg) {
9976        app.notResponding = true;
9977        app.notRespondingReport = generateProcessError(app,
9978                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9979                activity, shortMsg, longMsg, null);
9980        startAppProblemLocked(app);
9981        app.stopFreezingAllLocked();
9982    }
9983
9984    /**
9985     * Generate a process error record, suitable for attachment to a ProcessRecord.
9986     *
9987     * @param app The ProcessRecord in which the error occurred.
9988     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9989     *                      ActivityManager.AppErrorStateInfo
9990     * @param activity The activity associated with the crash, if known.
9991     * @param shortMsg Short message describing the crash.
9992     * @param longMsg Long message describing the crash.
9993     * @param stackTrace Full crash stack trace, may be null.
9994     *
9995     * @return Returns a fully-formed AppErrorStateInfo record.
9996     */
9997    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9998            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9999        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10000
10001        report.condition = condition;
10002        report.processName = app.processName;
10003        report.pid = app.pid;
10004        report.uid = app.info.uid;
10005        report.tag = activity;
10006        report.shortMsg = shortMsg;
10007        report.longMsg = longMsg;
10008        report.stackTrace = stackTrace;
10009
10010        return report;
10011    }
10012
10013    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10014        synchronized (this) {
10015            app.crashing = false;
10016            app.crashingReport = null;
10017            app.notResponding = false;
10018            app.notRespondingReport = null;
10019            if (app.anrDialog == fromDialog) {
10020                app.anrDialog = null;
10021            }
10022            if (app.waitDialog == fromDialog) {
10023                app.waitDialog = null;
10024            }
10025            if (app.pid > 0 && app.pid != MY_PID) {
10026                handleAppCrashLocked(app, null, null, null);
10027                killUnneededProcessLocked(app, "user request after error");
10028            }
10029        }
10030    }
10031
10032    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10033            String stackTrace) {
10034        long now = SystemClock.uptimeMillis();
10035
10036        Long crashTime;
10037        if (!app.isolated) {
10038            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10039        } else {
10040            crashTime = null;
10041        }
10042        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10043            // This process loses!
10044            Slog.w(TAG, "Process " + app.info.processName
10045                    + " has crashed too many times: killing!");
10046            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10047                    app.userId, app.info.processName, app.uid);
10048            mStackSupervisor.handleAppCrashLocked(app);
10049            if (!app.persistent) {
10050                // We don't want to start this process again until the user
10051                // explicitly does so...  but for persistent process, we really
10052                // need to keep it running.  If a persistent process is actually
10053                // repeatedly crashing, then badness for everyone.
10054                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10055                        app.info.processName);
10056                if (!app.isolated) {
10057                    // XXX We don't have a way to mark isolated processes
10058                    // as bad, since they don't have a peristent identity.
10059                    mBadProcesses.put(app.info.processName, app.uid,
10060                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10061                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10062                }
10063                app.bad = true;
10064                app.removed = true;
10065                // Don't let services in this process be restarted and potentially
10066                // annoy the user repeatedly.  Unless it is persistent, since those
10067                // processes run critical code.
10068                removeProcessLocked(app, false, false, "crash");
10069                mStackSupervisor.resumeTopActivitiesLocked();
10070                return false;
10071            }
10072            mStackSupervisor.resumeTopActivitiesLocked();
10073        } else {
10074            mStackSupervisor.finishTopRunningActivityLocked(app);
10075        }
10076
10077        // Bump up the crash count of any services currently running in the proc.
10078        for (int i=app.services.size()-1; i>=0; i--) {
10079            // Any services running in the application need to be placed
10080            // back in the pending list.
10081            ServiceRecord sr = app.services.valueAt(i);
10082            sr.crashCount++;
10083        }
10084
10085        // If the crashing process is what we consider to be the "home process" and it has been
10086        // replaced by a third-party app, clear the package preferred activities from packages
10087        // with a home activity running in the process to prevent a repeatedly crashing app
10088        // from blocking the user to manually clear the list.
10089        final ArrayList<ActivityRecord> activities = app.activities;
10090        if (app == mHomeProcess && activities.size() > 0
10091                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10092            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10093                final ActivityRecord r = activities.get(activityNdx);
10094                if (r.isHomeActivity()) {
10095                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10096                    try {
10097                        ActivityThread.getPackageManager()
10098                                .clearPackagePreferredActivities(r.packageName);
10099                    } catch (RemoteException c) {
10100                        // pm is in same process, this will never happen.
10101                    }
10102                }
10103            }
10104        }
10105
10106        if (!app.isolated) {
10107            // XXX Can't keep track of crash times for isolated processes,
10108            // because they don't have a perisistent identity.
10109            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10110        }
10111
10112        return true;
10113    }
10114
10115    void startAppProblemLocked(ProcessRecord app) {
10116        if (app.userId == mCurrentUserId) {
10117            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10118                    mContext, app.info.packageName, app.info.flags);
10119        } else {
10120            // If this app is not running under the current user, then we
10121            // can't give it a report button because that would require
10122            // launching the report UI under a different user.
10123            app.errorReportReceiver = null;
10124        }
10125        skipCurrentReceiverLocked(app);
10126    }
10127
10128    void skipCurrentReceiverLocked(ProcessRecord app) {
10129        for (BroadcastQueue queue : mBroadcastQueues) {
10130            queue.skipCurrentReceiverLocked(app);
10131        }
10132    }
10133
10134    /**
10135     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10136     * The application process will exit immediately after this call returns.
10137     * @param app object of the crashing app, null for the system server
10138     * @param crashInfo describing the exception
10139     */
10140    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10141        ProcessRecord r = findAppProcess(app, "Crash");
10142        final String processName = app == null ? "system_server"
10143                : (r == null ? "unknown" : r.processName);
10144
10145        handleApplicationCrashInner("crash", r, processName, crashInfo);
10146    }
10147
10148    /* Native crash reporting uses this inner version because it needs to be somewhat
10149     * decoupled from the AM-managed cleanup lifecycle
10150     */
10151    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10152            ApplicationErrorReport.CrashInfo crashInfo) {
10153        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10154                UserHandle.getUserId(Binder.getCallingUid()), processName,
10155                r == null ? -1 : r.info.flags,
10156                crashInfo.exceptionClassName,
10157                crashInfo.exceptionMessage,
10158                crashInfo.throwFileName,
10159                crashInfo.throwLineNumber);
10160
10161        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10162
10163        crashApplication(r, crashInfo);
10164    }
10165
10166    public void handleApplicationStrictModeViolation(
10167            IBinder app,
10168            int violationMask,
10169            StrictMode.ViolationInfo info) {
10170        ProcessRecord r = findAppProcess(app, "StrictMode");
10171        if (r == null) {
10172            return;
10173        }
10174
10175        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10176            Integer stackFingerprint = info.hashCode();
10177            boolean logIt = true;
10178            synchronized (mAlreadyLoggedViolatedStacks) {
10179                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10180                    logIt = false;
10181                    // TODO: sub-sample into EventLog for these, with
10182                    // the info.durationMillis?  Then we'd get
10183                    // the relative pain numbers, without logging all
10184                    // the stack traces repeatedly.  We'd want to do
10185                    // likewise in the client code, which also does
10186                    // dup suppression, before the Binder call.
10187                } else {
10188                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10189                        mAlreadyLoggedViolatedStacks.clear();
10190                    }
10191                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10192                }
10193            }
10194            if (logIt) {
10195                logStrictModeViolationToDropBox(r, info);
10196            }
10197        }
10198
10199        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10200            AppErrorResult result = new AppErrorResult();
10201            synchronized (this) {
10202                final long origId = Binder.clearCallingIdentity();
10203
10204                Message msg = Message.obtain();
10205                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10206                HashMap<String, Object> data = new HashMap<String, Object>();
10207                data.put("result", result);
10208                data.put("app", r);
10209                data.put("violationMask", violationMask);
10210                data.put("info", info);
10211                msg.obj = data;
10212                mHandler.sendMessage(msg);
10213
10214                Binder.restoreCallingIdentity(origId);
10215            }
10216            int res = result.get();
10217            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10218        }
10219    }
10220
10221    // Depending on the policy in effect, there could be a bunch of
10222    // these in quick succession so we try to batch these together to
10223    // minimize disk writes, number of dropbox entries, and maximize
10224    // compression, by having more fewer, larger records.
10225    private void logStrictModeViolationToDropBox(
10226            ProcessRecord process,
10227            StrictMode.ViolationInfo info) {
10228        if (info == null) {
10229            return;
10230        }
10231        final boolean isSystemApp = process == null ||
10232                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10233                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10234        final String processName = process == null ? "unknown" : process.processName;
10235        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10236        final DropBoxManager dbox = (DropBoxManager)
10237                mContext.getSystemService(Context.DROPBOX_SERVICE);
10238
10239        // Exit early if the dropbox isn't configured to accept this report type.
10240        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10241
10242        boolean bufferWasEmpty;
10243        boolean needsFlush;
10244        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10245        synchronized (sb) {
10246            bufferWasEmpty = sb.length() == 0;
10247            appendDropBoxProcessHeaders(process, processName, sb);
10248            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10249            sb.append("System-App: ").append(isSystemApp).append("\n");
10250            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10251            if (info.violationNumThisLoop != 0) {
10252                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10253            }
10254            if (info.numAnimationsRunning != 0) {
10255                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10256            }
10257            if (info.broadcastIntentAction != null) {
10258                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10259            }
10260            if (info.durationMillis != -1) {
10261                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10262            }
10263            if (info.numInstances != -1) {
10264                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10265            }
10266            if (info.tags != null) {
10267                for (String tag : info.tags) {
10268                    sb.append("Span-Tag: ").append(tag).append("\n");
10269                }
10270            }
10271            sb.append("\n");
10272            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10273                sb.append(info.crashInfo.stackTrace);
10274            }
10275            sb.append("\n");
10276
10277            // Only buffer up to ~64k.  Various logging bits truncate
10278            // things at 128k.
10279            needsFlush = (sb.length() > 64 * 1024);
10280        }
10281
10282        // Flush immediately if the buffer's grown too large, or this
10283        // is a non-system app.  Non-system apps are isolated with a
10284        // different tag & policy and not batched.
10285        //
10286        // Batching is useful during internal testing with
10287        // StrictMode settings turned up high.  Without batching,
10288        // thousands of separate files could be created on boot.
10289        if (!isSystemApp || needsFlush) {
10290            new Thread("Error dump: " + dropboxTag) {
10291                @Override
10292                public void run() {
10293                    String report;
10294                    synchronized (sb) {
10295                        report = sb.toString();
10296                        sb.delete(0, sb.length());
10297                        sb.trimToSize();
10298                    }
10299                    if (report.length() != 0) {
10300                        dbox.addText(dropboxTag, report);
10301                    }
10302                }
10303            }.start();
10304            return;
10305        }
10306
10307        // System app batching:
10308        if (!bufferWasEmpty) {
10309            // An existing dropbox-writing thread is outstanding, so
10310            // we don't need to start it up.  The existing thread will
10311            // catch the buffer appends we just did.
10312            return;
10313        }
10314
10315        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10316        // (After this point, we shouldn't access AMS internal data structures.)
10317        new Thread("Error dump: " + dropboxTag) {
10318            @Override
10319            public void run() {
10320                // 5 second sleep to let stacks arrive and be batched together
10321                try {
10322                    Thread.sleep(5000);  // 5 seconds
10323                } catch (InterruptedException e) {}
10324
10325                String errorReport;
10326                synchronized (mStrictModeBuffer) {
10327                    errorReport = mStrictModeBuffer.toString();
10328                    if (errorReport.length() == 0) {
10329                        return;
10330                    }
10331                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10332                    mStrictModeBuffer.trimToSize();
10333                }
10334                dbox.addText(dropboxTag, errorReport);
10335            }
10336        }.start();
10337    }
10338
10339    /**
10340     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10341     * @param app object of the crashing app, null for the system server
10342     * @param tag reported by the caller
10343     * @param crashInfo describing the context of the error
10344     * @return true if the process should exit immediately (WTF is fatal)
10345     */
10346    public boolean handleApplicationWtf(IBinder app, String tag,
10347            ApplicationErrorReport.CrashInfo crashInfo) {
10348        ProcessRecord r = findAppProcess(app, "WTF");
10349        final String processName = app == null ? "system_server"
10350                : (r == null ? "unknown" : r.processName);
10351
10352        EventLog.writeEvent(EventLogTags.AM_WTF,
10353                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10354                processName,
10355                r == null ? -1 : r.info.flags,
10356                tag, crashInfo.exceptionMessage);
10357
10358        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10359
10360        if (r != null && r.pid != Process.myPid() &&
10361                Settings.Global.getInt(mContext.getContentResolver(),
10362                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10363            crashApplication(r, crashInfo);
10364            return true;
10365        } else {
10366            return false;
10367        }
10368    }
10369
10370    /**
10371     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10372     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10373     */
10374    private ProcessRecord findAppProcess(IBinder app, String reason) {
10375        if (app == null) {
10376            return null;
10377        }
10378
10379        synchronized (this) {
10380            final int NP = mProcessNames.getMap().size();
10381            for (int ip=0; ip<NP; ip++) {
10382                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10383                final int NA = apps.size();
10384                for (int ia=0; ia<NA; ia++) {
10385                    ProcessRecord p = apps.valueAt(ia);
10386                    if (p.thread != null && p.thread.asBinder() == app) {
10387                        return p;
10388                    }
10389                }
10390            }
10391
10392            Slog.w(TAG, "Can't find mystery application for " + reason
10393                    + " from pid=" + Binder.getCallingPid()
10394                    + " uid=" + Binder.getCallingUid() + ": " + app);
10395            return null;
10396        }
10397    }
10398
10399    /**
10400     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10401     * to append various headers to the dropbox log text.
10402     */
10403    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10404            StringBuilder sb) {
10405        // Watchdog thread ends up invoking this function (with
10406        // a null ProcessRecord) to add the stack file to dropbox.
10407        // Do not acquire a lock on this (am) in such cases, as it
10408        // could cause a potential deadlock, if and when watchdog
10409        // is invoked due to unavailability of lock on am and it
10410        // would prevent watchdog from killing system_server.
10411        if (process == null) {
10412            sb.append("Process: ").append(processName).append("\n");
10413            return;
10414        }
10415        // Note: ProcessRecord 'process' is guarded by the service
10416        // instance.  (notably process.pkgList, which could otherwise change
10417        // concurrently during execution of this method)
10418        synchronized (this) {
10419            sb.append("Process: ").append(processName).append("\n");
10420            int flags = process.info.flags;
10421            IPackageManager pm = AppGlobals.getPackageManager();
10422            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10423            for (int ip=0; ip<process.pkgList.size(); ip++) {
10424                String pkg = process.pkgList.keyAt(ip);
10425                sb.append("Package: ").append(pkg);
10426                try {
10427                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10428                    if (pi != null) {
10429                        sb.append(" v").append(pi.versionCode);
10430                        if (pi.versionName != null) {
10431                            sb.append(" (").append(pi.versionName).append(")");
10432                        }
10433                    }
10434                } catch (RemoteException e) {
10435                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10436                }
10437                sb.append("\n");
10438            }
10439        }
10440    }
10441
10442    private static String processClass(ProcessRecord process) {
10443        if (process == null || process.pid == MY_PID) {
10444            return "system_server";
10445        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10446            return "system_app";
10447        } else {
10448            return "data_app";
10449        }
10450    }
10451
10452    /**
10453     * Write a description of an error (crash, WTF, ANR) to the drop box.
10454     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10455     * @param process which caused the error, null means the system server
10456     * @param activity which triggered the error, null if unknown
10457     * @param parent activity related to the error, null if unknown
10458     * @param subject line related to the error, null if absent
10459     * @param report in long form describing the error, null if absent
10460     * @param logFile to include in the report, null if none
10461     * @param crashInfo giving an application stack trace, null if absent
10462     */
10463    public void addErrorToDropBox(String eventType,
10464            ProcessRecord process, String processName, ActivityRecord activity,
10465            ActivityRecord parent, String subject,
10466            final String report, final File logFile,
10467            final ApplicationErrorReport.CrashInfo crashInfo) {
10468        // NOTE -- this must never acquire the ActivityManagerService lock,
10469        // otherwise the watchdog may be prevented from resetting the system.
10470
10471        final String dropboxTag = processClass(process) + "_" + eventType;
10472        final DropBoxManager dbox = (DropBoxManager)
10473                mContext.getSystemService(Context.DROPBOX_SERVICE);
10474
10475        // Exit early if the dropbox isn't configured to accept this report type.
10476        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10477
10478        final StringBuilder sb = new StringBuilder(1024);
10479        appendDropBoxProcessHeaders(process, processName, sb);
10480        if (activity != null) {
10481            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10482        }
10483        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10484            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10485        }
10486        if (parent != null && parent != activity) {
10487            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10488        }
10489        if (subject != null) {
10490            sb.append("Subject: ").append(subject).append("\n");
10491        }
10492        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10493        if (Debug.isDebuggerConnected()) {
10494            sb.append("Debugger: Connected\n");
10495        }
10496        sb.append("\n");
10497
10498        // Do the rest in a worker thread to avoid blocking the caller on I/O
10499        // (After this point, we shouldn't access AMS internal data structures.)
10500        Thread worker = new Thread("Error dump: " + dropboxTag) {
10501            @Override
10502            public void run() {
10503                if (report != null) {
10504                    sb.append(report);
10505                }
10506                if (logFile != null) {
10507                    try {
10508                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10509                                    "\n\n[[TRUNCATED]]"));
10510                    } catch (IOException e) {
10511                        Slog.e(TAG, "Error reading " + logFile, e);
10512                    }
10513                }
10514                if (crashInfo != null && crashInfo.stackTrace != null) {
10515                    sb.append(crashInfo.stackTrace);
10516                }
10517
10518                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10519                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10520                if (lines > 0) {
10521                    sb.append("\n");
10522
10523                    // Merge several logcat streams, and take the last N lines
10524                    InputStreamReader input = null;
10525                    try {
10526                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10527                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10528                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10529
10530                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10531                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10532                        input = new InputStreamReader(logcat.getInputStream());
10533
10534                        int num;
10535                        char[] buf = new char[8192];
10536                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10537                    } catch (IOException e) {
10538                        Slog.e(TAG, "Error running logcat", e);
10539                    } finally {
10540                        if (input != null) try { input.close(); } catch (IOException e) {}
10541                    }
10542                }
10543
10544                dbox.addText(dropboxTag, sb.toString());
10545            }
10546        };
10547
10548        if (process == null) {
10549            // If process is null, we are being called from some internal code
10550            // and may be about to die -- run this synchronously.
10551            worker.run();
10552        } else {
10553            worker.start();
10554        }
10555    }
10556
10557    /**
10558     * Bring up the "unexpected error" dialog box for a crashing app.
10559     * Deal with edge cases (intercepts from instrumented applications,
10560     * ActivityController, error intent receivers, that sort of thing).
10561     * @param r the application crashing
10562     * @param crashInfo describing the failure
10563     */
10564    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10565        long timeMillis = System.currentTimeMillis();
10566        String shortMsg = crashInfo.exceptionClassName;
10567        String longMsg = crashInfo.exceptionMessage;
10568        String stackTrace = crashInfo.stackTrace;
10569        if (shortMsg != null && longMsg != null) {
10570            longMsg = shortMsg + ": " + longMsg;
10571        } else if (shortMsg != null) {
10572            longMsg = shortMsg;
10573        }
10574
10575        AppErrorResult result = new AppErrorResult();
10576        synchronized (this) {
10577            if (mController != null) {
10578                try {
10579                    String name = r != null ? r.processName : null;
10580                    int pid = r != null ? r.pid : Binder.getCallingPid();
10581                    if (!mController.appCrashed(name, pid,
10582                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10583                        Slog.w(TAG, "Force-killing crashed app " + name
10584                                + " at watcher's request");
10585                        Process.killProcess(pid);
10586                        return;
10587                    }
10588                } catch (RemoteException e) {
10589                    mController = null;
10590                    Watchdog.getInstance().setActivityController(null);
10591                }
10592            }
10593
10594            final long origId = Binder.clearCallingIdentity();
10595
10596            // If this process is running instrumentation, finish it.
10597            if (r != null && r.instrumentationClass != null) {
10598                Slog.w(TAG, "Error in app " + r.processName
10599                      + " running instrumentation " + r.instrumentationClass + ":");
10600                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10601                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10602                Bundle info = new Bundle();
10603                info.putString("shortMsg", shortMsg);
10604                info.putString("longMsg", longMsg);
10605                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10606                Binder.restoreCallingIdentity(origId);
10607                return;
10608            }
10609
10610            // If we can't identify the process or it's already exceeded its crash quota,
10611            // quit right away without showing a crash dialog.
10612            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10613                Binder.restoreCallingIdentity(origId);
10614                return;
10615            }
10616
10617            Message msg = Message.obtain();
10618            msg.what = SHOW_ERROR_MSG;
10619            HashMap data = new HashMap();
10620            data.put("result", result);
10621            data.put("app", r);
10622            msg.obj = data;
10623            mHandler.sendMessage(msg);
10624
10625            Binder.restoreCallingIdentity(origId);
10626        }
10627
10628        int res = result.get();
10629
10630        Intent appErrorIntent = null;
10631        synchronized (this) {
10632            if (r != null && !r.isolated) {
10633                // XXX Can't keep track of crash time for isolated processes,
10634                // since they don't have a persistent identity.
10635                mProcessCrashTimes.put(r.info.processName, r.uid,
10636                        SystemClock.uptimeMillis());
10637            }
10638            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10639                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10640            }
10641        }
10642
10643        if (appErrorIntent != null) {
10644            try {
10645                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10646            } catch (ActivityNotFoundException e) {
10647                Slog.w(TAG, "bug report receiver dissappeared", e);
10648            }
10649        }
10650    }
10651
10652    Intent createAppErrorIntentLocked(ProcessRecord r,
10653            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10654        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10655        if (report == null) {
10656            return null;
10657        }
10658        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10659        result.setComponent(r.errorReportReceiver);
10660        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10661        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10662        return result;
10663    }
10664
10665    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10666            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10667        if (r.errorReportReceiver == null) {
10668            return null;
10669        }
10670
10671        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10672            return null;
10673        }
10674
10675        ApplicationErrorReport report = new ApplicationErrorReport();
10676        report.packageName = r.info.packageName;
10677        report.installerPackageName = r.errorReportReceiver.getPackageName();
10678        report.processName = r.processName;
10679        report.time = timeMillis;
10680        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10681
10682        if (r.crashing || r.forceCrashReport) {
10683            report.type = ApplicationErrorReport.TYPE_CRASH;
10684            report.crashInfo = crashInfo;
10685        } else if (r.notResponding) {
10686            report.type = ApplicationErrorReport.TYPE_ANR;
10687            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10688
10689            report.anrInfo.activity = r.notRespondingReport.tag;
10690            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10691            report.anrInfo.info = r.notRespondingReport.longMsg;
10692        }
10693
10694        return report;
10695    }
10696
10697    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10698        enforceNotIsolatedCaller("getProcessesInErrorState");
10699        // assume our apps are happy - lazy create the list
10700        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10701
10702        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10703                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10704        int userId = UserHandle.getUserId(Binder.getCallingUid());
10705
10706        synchronized (this) {
10707
10708            // iterate across all processes
10709            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10710                ProcessRecord app = mLruProcesses.get(i);
10711                if (!allUsers && app.userId != userId) {
10712                    continue;
10713                }
10714                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10715                    // This one's in trouble, so we'll generate a report for it
10716                    // crashes are higher priority (in case there's a crash *and* an anr)
10717                    ActivityManager.ProcessErrorStateInfo report = null;
10718                    if (app.crashing) {
10719                        report = app.crashingReport;
10720                    } else if (app.notResponding) {
10721                        report = app.notRespondingReport;
10722                    }
10723
10724                    if (report != null) {
10725                        if (errList == null) {
10726                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10727                        }
10728                        errList.add(report);
10729                    } else {
10730                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10731                                " crashing = " + app.crashing +
10732                                " notResponding = " + app.notResponding);
10733                    }
10734                }
10735            }
10736        }
10737
10738        return errList;
10739    }
10740
10741    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10742        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10743            if (currApp != null) {
10744                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10745            }
10746            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10747        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10748            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10749        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10750            if (currApp != null) {
10751                currApp.lru = 0;
10752            }
10753            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10754        } else if (adj >= ProcessList.SERVICE_ADJ) {
10755            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10756        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10757            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10758        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10759            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10760        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10761            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10762        } else {
10763            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10764        }
10765    }
10766
10767    private void fillInProcMemInfo(ProcessRecord app,
10768            ActivityManager.RunningAppProcessInfo outInfo) {
10769        outInfo.pid = app.pid;
10770        outInfo.uid = app.info.uid;
10771        if (mHeavyWeightProcess == app) {
10772            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10773        }
10774        if (app.persistent) {
10775            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10776        }
10777        if (app.activities.size() > 0) {
10778            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10779        }
10780        outInfo.lastTrimLevel = app.trimMemoryLevel;
10781        int adj = app.curAdj;
10782        outInfo.importance = oomAdjToImportance(adj, outInfo);
10783        outInfo.importanceReasonCode = app.adjTypeCode;
10784        outInfo.processState = app.curProcState;
10785    }
10786
10787    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10788        enforceNotIsolatedCaller("getRunningAppProcesses");
10789        // Lazy instantiation of list
10790        List<ActivityManager.RunningAppProcessInfo> runList = null;
10791        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10792                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10793        int userId = UserHandle.getUserId(Binder.getCallingUid());
10794        synchronized (this) {
10795            // Iterate across all processes
10796            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10797                ProcessRecord app = mLruProcesses.get(i);
10798                if (!allUsers && app.userId != userId) {
10799                    continue;
10800                }
10801                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10802                    // Generate process state info for running application
10803                    ActivityManager.RunningAppProcessInfo currApp =
10804                        new ActivityManager.RunningAppProcessInfo(app.processName,
10805                                app.pid, app.getPackageList());
10806                    fillInProcMemInfo(app, currApp);
10807                    if (app.adjSource instanceof ProcessRecord) {
10808                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10809                        currApp.importanceReasonImportance = oomAdjToImportance(
10810                                app.adjSourceOom, null);
10811                    } else if (app.adjSource instanceof ActivityRecord) {
10812                        ActivityRecord r = (ActivityRecord)app.adjSource;
10813                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10814                    }
10815                    if (app.adjTarget instanceof ComponentName) {
10816                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10817                    }
10818                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10819                    //        + " lru=" + currApp.lru);
10820                    if (runList == null) {
10821                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10822                    }
10823                    runList.add(currApp);
10824                }
10825            }
10826        }
10827        return runList;
10828    }
10829
10830    public List<ApplicationInfo> getRunningExternalApplications() {
10831        enforceNotIsolatedCaller("getRunningExternalApplications");
10832        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10833        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10834        if (runningApps != null && runningApps.size() > 0) {
10835            Set<String> extList = new HashSet<String>();
10836            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10837                if (app.pkgList != null) {
10838                    for (String pkg : app.pkgList) {
10839                        extList.add(pkg);
10840                    }
10841                }
10842            }
10843            IPackageManager pm = AppGlobals.getPackageManager();
10844            for (String pkg : extList) {
10845                try {
10846                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10847                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10848                        retList.add(info);
10849                    }
10850                } catch (RemoteException e) {
10851                }
10852            }
10853        }
10854        return retList;
10855    }
10856
10857    @Override
10858    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10859        enforceNotIsolatedCaller("getMyMemoryState");
10860        synchronized (this) {
10861            ProcessRecord proc;
10862            synchronized (mPidsSelfLocked) {
10863                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10864            }
10865            fillInProcMemInfo(proc, outInfo);
10866        }
10867    }
10868
10869    @Override
10870    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10871        if (checkCallingPermission(android.Manifest.permission.DUMP)
10872                != PackageManager.PERMISSION_GRANTED) {
10873            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10874                    + Binder.getCallingPid()
10875                    + ", uid=" + Binder.getCallingUid()
10876                    + " without permission "
10877                    + android.Manifest.permission.DUMP);
10878            return;
10879        }
10880
10881        boolean dumpAll = false;
10882        boolean dumpClient = false;
10883        String dumpPackage = null;
10884
10885        int opti = 0;
10886        while (opti < args.length) {
10887            String opt = args[opti];
10888            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10889                break;
10890            }
10891            opti++;
10892            if ("-a".equals(opt)) {
10893                dumpAll = true;
10894            } else if ("-c".equals(opt)) {
10895                dumpClient = true;
10896            } else if ("-h".equals(opt)) {
10897                pw.println("Activity manager dump options:");
10898                pw.println("  [-a] [-c] [-h] [cmd] ...");
10899                pw.println("  cmd may be one of:");
10900                pw.println("    a[ctivities]: activity stack state");
10901                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10902                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10903                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10904                pw.println("    o[om]: out of memory management");
10905                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10906                pw.println("    provider [COMP_SPEC]: provider client-side state");
10907                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10908                pw.println("    service [COMP_SPEC]: service client-side state");
10909                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10910                pw.println("    all: dump all activities");
10911                pw.println("    top: dump the top activity");
10912                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10913                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10914                pw.println("    a partial substring in a component name, a");
10915                pw.println("    hex object identifier.");
10916                pw.println("  -a: include all available server state.");
10917                pw.println("  -c: include client state.");
10918                return;
10919            } else {
10920                pw.println("Unknown argument: " + opt + "; use -h for help");
10921            }
10922        }
10923
10924        long origId = Binder.clearCallingIdentity();
10925        boolean more = false;
10926        // Is the caller requesting to dump a particular piece of data?
10927        if (opti < args.length) {
10928            String cmd = args[opti];
10929            opti++;
10930            if ("activities".equals(cmd) || "a".equals(cmd)) {
10931                synchronized (this) {
10932                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10933                }
10934            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10935                String[] newArgs;
10936                String name;
10937                if (opti >= args.length) {
10938                    name = null;
10939                    newArgs = EMPTY_STRING_ARRAY;
10940                } else {
10941                    name = args[opti];
10942                    opti++;
10943                    newArgs = new String[args.length - opti];
10944                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10945                            args.length - opti);
10946                }
10947                synchronized (this) {
10948                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10949                }
10950            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10951                String[] newArgs;
10952                String name;
10953                if (opti >= args.length) {
10954                    name = null;
10955                    newArgs = EMPTY_STRING_ARRAY;
10956                } else {
10957                    name = args[opti];
10958                    opti++;
10959                    newArgs = new String[args.length - opti];
10960                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10961                            args.length - opti);
10962                }
10963                synchronized (this) {
10964                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10965                }
10966            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10967                String[] newArgs;
10968                String name;
10969                if (opti >= args.length) {
10970                    name = null;
10971                    newArgs = EMPTY_STRING_ARRAY;
10972                } else {
10973                    name = args[opti];
10974                    opti++;
10975                    newArgs = new String[args.length - opti];
10976                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10977                            args.length - opti);
10978                }
10979                synchronized (this) {
10980                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10981                }
10982            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10983                synchronized (this) {
10984                    dumpOomLocked(fd, pw, args, opti, true);
10985                }
10986            } else if ("provider".equals(cmd)) {
10987                String[] newArgs;
10988                String name;
10989                if (opti >= args.length) {
10990                    name = null;
10991                    newArgs = EMPTY_STRING_ARRAY;
10992                } else {
10993                    name = args[opti];
10994                    opti++;
10995                    newArgs = new String[args.length - opti];
10996                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10997                }
10998                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10999                    pw.println("No providers match: " + name);
11000                    pw.println("Use -h for help.");
11001                }
11002            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11003                synchronized (this) {
11004                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11005                }
11006            } else if ("service".equals(cmd)) {
11007                String[] newArgs;
11008                String name;
11009                if (opti >= args.length) {
11010                    name = null;
11011                    newArgs = EMPTY_STRING_ARRAY;
11012                } else {
11013                    name = args[opti];
11014                    opti++;
11015                    newArgs = new String[args.length - opti];
11016                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11017                            args.length - opti);
11018                }
11019                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11020                    pw.println("No services match: " + name);
11021                    pw.println("Use -h for help.");
11022                }
11023            } else if ("package".equals(cmd)) {
11024                String[] newArgs;
11025                if (opti >= args.length) {
11026                    pw.println("package: no package name specified");
11027                    pw.println("Use -h for help.");
11028                } else {
11029                    dumpPackage = args[opti];
11030                    opti++;
11031                    newArgs = new String[args.length - opti];
11032                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11033                            args.length - opti);
11034                    args = newArgs;
11035                    opti = 0;
11036                    more = true;
11037                }
11038            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11039                synchronized (this) {
11040                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11041                }
11042            } else {
11043                // Dumping a single activity?
11044                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11045                    pw.println("Bad activity command, or no activities match: " + cmd);
11046                    pw.println("Use -h for help.");
11047                }
11048            }
11049            if (!more) {
11050                Binder.restoreCallingIdentity(origId);
11051                return;
11052            }
11053        }
11054
11055        // No piece of data specified, dump everything.
11056        synchronized (this) {
11057            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11058            pw.println();
11059            if (dumpAll) {
11060                pw.println("-------------------------------------------------------------------------------");
11061            }
11062            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11063            pw.println();
11064            if (dumpAll) {
11065                pw.println("-------------------------------------------------------------------------------");
11066            }
11067            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11068            pw.println();
11069            if (dumpAll) {
11070                pw.println("-------------------------------------------------------------------------------");
11071            }
11072            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11073            pw.println();
11074            if (dumpAll) {
11075                pw.println("-------------------------------------------------------------------------------");
11076            }
11077            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11078            pw.println();
11079            if (dumpAll) {
11080                pw.println("-------------------------------------------------------------------------------");
11081            }
11082            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11083        }
11084        Binder.restoreCallingIdentity(origId);
11085    }
11086
11087    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11088            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11089        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11090
11091        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11092                dumpPackage);
11093        boolean needSep = printedAnything;
11094
11095        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11096                dumpPackage, needSep, "  mFocusedActivity: ");
11097        if (printed) {
11098            printedAnything = true;
11099            needSep = false;
11100        }
11101
11102        if (dumpPackage == null) {
11103            if (needSep) {
11104                pw.println();
11105            }
11106            needSep = true;
11107            printedAnything = true;
11108            mStackSupervisor.dump(pw, "  ");
11109        }
11110
11111        if (mRecentTasks.size() > 0) {
11112            boolean printedHeader = false;
11113
11114            final int N = mRecentTasks.size();
11115            for (int i=0; i<N; i++) {
11116                TaskRecord tr = mRecentTasks.get(i);
11117                if (dumpPackage != null) {
11118                    if (tr.realActivity == null ||
11119                            !dumpPackage.equals(tr.realActivity)) {
11120                        continue;
11121                    }
11122                }
11123                if (!printedHeader) {
11124                    if (needSep) {
11125                        pw.println();
11126                    }
11127                    pw.println("  Recent tasks:");
11128                    printedHeader = true;
11129                    printedAnything = true;
11130                }
11131                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11132                        pw.println(tr);
11133                if (dumpAll) {
11134                    mRecentTasks.get(i).dump(pw, "    ");
11135                }
11136            }
11137        }
11138
11139        if (!printedAnything) {
11140            pw.println("  (nothing)");
11141        }
11142    }
11143
11144    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11145            int opti, boolean dumpAll, String dumpPackage) {
11146        boolean needSep = false;
11147        boolean printedAnything = false;
11148        int numPers = 0;
11149
11150        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11151
11152        if (dumpAll) {
11153            final int NP = mProcessNames.getMap().size();
11154            for (int ip=0; ip<NP; ip++) {
11155                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11156                final int NA = procs.size();
11157                for (int ia=0; ia<NA; ia++) {
11158                    ProcessRecord r = procs.valueAt(ia);
11159                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11160                        continue;
11161                    }
11162                    if (!needSep) {
11163                        pw.println("  All known processes:");
11164                        needSep = true;
11165                        printedAnything = true;
11166                    }
11167                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11168                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11169                        pw.print(" "); pw.println(r);
11170                    r.dump(pw, "    ");
11171                    if (r.persistent) {
11172                        numPers++;
11173                    }
11174                }
11175            }
11176        }
11177
11178        if (mIsolatedProcesses.size() > 0) {
11179            boolean printed = false;
11180            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11181                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11182                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11183                    continue;
11184                }
11185                if (!printed) {
11186                    if (needSep) {
11187                        pw.println();
11188                    }
11189                    pw.println("  Isolated process list (sorted by uid):");
11190                    printedAnything = true;
11191                    printed = true;
11192                    needSep = true;
11193                }
11194                pw.println(String.format("%sIsolated #%2d: %s",
11195                        "    ", i, r.toString()));
11196            }
11197        }
11198
11199        if (mLruProcesses.size() > 0) {
11200            if (needSep) {
11201                pw.println();
11202            }
11203            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11204                    pw.print(" total, non-act at ");
11205                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11206                    pw.print(", non-svc at ");
11207                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11208                    pw.println("):");
11209            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11210            needSep = true;
11211            printedAnything = true;
11212        }
11213
11214        if (dumpAll || dumpPackage != null) {
11215            synchronized (mPidsSelfLocked) {
11216                boolean printed = false;
11217                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11218                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11219                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11220                        continue;
11221                    }
11222                    if (!printed) {
11223                        if (needSep) pw.println();
11224                        needSep = true;
11225                        pw.println("  PID mappings:");
11226                        printed = true;
11227                        printedAnything = true;
11228                    }
11229                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11230                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11231                }
11232            }
11233        }
11234
11235        if (mForegroundProcesses.size() > 0) {
11236            synchronized (mPidsSelfLocked) {
11237                boolean printed = false;
11238                for (int i=0; i<mForegroundProcesses.size(); i++) {
11239                    ProcessRecord r = mPidsSelfLocked.get(
11240                            mForegroundProcesses.valueAt(i).pid);
11241                    if (dumpPackage != null && (r == null
11242                            || !r.pkgList.containsKey(dumpPackage))) {
11243                        continue;
11244                    }
11245                    if (!printed) {
11246                        if (needSep) pw.println();
11247                        needSep = true;
11248                        pw.println("  Foreground Processes:");
11249                        printed = true;
11250                        printedAnything = true;
11251                    }
11252                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11253                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11254                }
11255            }
11256        }
11257
11258        if (mPersistentStartingProcesses.size() > 0) {
11259            if (needSep) pw.println();
11260            needSep = true;
11261            printedAnything = true;
11262            pw.println("  Persisent processes that are starting:");
11263            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11264                    "Starting Norm", "Restarting PERS", dumpPackage);
11265        }
11266
11267        if (mRemovedProcesses.size() > 0) {
11268            if (needSep) pw.println();
11269            needSep = true;
11270            printedAnything = true;
11271            pw.println("  Processes that are being removed:");
11272            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11273                    "Removed Norm", "Removed PERS", dumpPackage);
11274        }
11275
11276        if (mProcessesOnHold.size() > 0) {
11277            if (needSep) pw.println();
11278            needSep = true;
11279            printedAnything = true;
11280            pw.println("  Processes that are on old until the system is ready:");
11281            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11282                    "OnHold Norm", "OnHold PERS", dumpPackage);
11283        }
11284
11285        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11286
11287        if (mProcessCrashTimes.getMap().size() > 0) {
11288            boolean printed = false;
11289            long now = SystemClock.uptimeMillis();
11290            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11291            final int NP = pmap.size();
11292            for (int ip=0; ip<NP; ip++) {
11293                String pname = pmap.keyAt(ip);
11294                SparseArray<Long> uids = pmap.valueAt(ip);
11295                final int N = uids.size();
11296                for (int i=0; i<N; i++) {
11297                    int puid = uids.keyAt(i);
11298                    ProcessRecord r = mProcessNames.get(pname, puid);
11299                    if (dumpPackage != null && (r == null
11300                            || !r.pkgList.containsKey(dumpPackage))) {
11301                        continue;
11302                    }
11303                    if (!printed) {
11304                        if (needSep) pw.println();
11305                        needSep = true;
11306                        pw.println("  Time since processes crashed:");
11307                        printed = true;
11308                        printedAnything = true;
11309                    }
11310                    pw.print("    Process "); pw.print(pname);
11311                            pw.print(" uid "); pw.print(puid);
11312                            pw.print(": last crashed ");
11313                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11314                            pw.println(" ago");
11315                }
11316            }
11317        }
11318
11319        if (mBadProcesses.getMap().size() > 0) {
11320            boolean printed = false;
11321            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11322            final int NP = pmap.size();
11323            for (int ip=0; ip<NP; ip++) {
11324                String pname = pmap.keyAt(ip);
11325                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11326                final int N = uids.size();
11327                for (int i=0; i<N; i++) {
11328                    int puid = uids.keyAt(i);
11329                    ProcessRecord r = mProcessNames.get(pname, puid);
11330                    if (dumpPackage != null && (r == null
11331                            || !r.pkgList.containsKey(dumpPackage))) {
11332                        continue;
11333                    }
11334                    if (!printed) {
11335                        if (needSep) pw.println();
11336                        needSep = true;
11337                        pw.println("  Bad processes:");
11338                        printedAnything = true;
11339                    }
11340                    BadProcessInfo info = uids.valueAt(i);
11341                    pw.print("    Bad process "); pw.print(pname);
11342                            pw.print(" uid "); pw.print(puid);
11343                            pw.print(": crashed at time "); pw.println(info.time);
11344                    if (info.shortMsg != null) {
11345                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11346                    }
11347                    if (info.longMsg != null) {
11348                        pw.print("      Long msg: "); pw.println(info.longMsg);
11349                    }
11350                    if (info.stack != null) {
11351                        pw.println("      Stack:");
11352                        int lastPos = 0;
11353                        for (int pos=0; pos<info.stack.length(); pos++) {
11354                            if (info.stack.charAt(pos) == '\n') {
11355                                pw.print("        ");
11356                                pw.write(info.stack, lastPos, pos-lastPos);
11357                                pw.println();
11358                                lastPos = pos+1;
11359                            }
11360                        }
11361                        if (lastPos < info.stack.length()) {
11362                            pw.print("        ");
11363                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11364                            pw.println();
11365                        }
11366                    }
11367                }
11368            }
11369        }
11370
11371        if (dumpPackage == null) {
11372            pw.println();
11373            needSep = false;
11374            pw.println("  mStartedUsers:");
11375            for (int i=0; i<mStartedUsers.size(); i++) {
11376                UserStartedState uss = mStartedUsers.valueAt(i);
11377                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11378                        pw.print(": "); uss.dump("", pw);
11379            }
11380            pw.print("  mStartedUserArray: [");
11381            for (int i=0; i<mStartedUserArray.length; i++) {
11382                if (i > 0) pw.print(", ");
11383                pw.print(mStartedUserArray[i]);
11384            }
11385            pw.println("]");
11386            pw.print("  mUserLru: [");
11387            for (int i=0; i<mUserLru.size(); i++) {
11388                if (i > 0) pw.print(", ");
11389                pw.print(mUserLru.get(i));
11390            }
11391            pw.println("]");
11392            if (dumpAll) {
11393                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11394            }
11395        }
11396        if (mHomeProcess != null && (dumpPackage == null
11397                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11398            if (needSep) {
11399                pw.println();
11400                needSep = false;
11401            }
11402            pw.println("  mHomeProcess: " + mHomeProcess);
11403        }
11404        if (mPreviousProcess != null && (dumpPackage == null
11405                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11406            if (needSep) {
11407                pw.println();
11408                needSep = false;
11409            }
11410            pw.println("  mPreviousProcess: " + mPreviousProcess);
11411        }
11412        if (dumpAll) {
11413            StringBuilder sb = new StringBuilder(128);
11414            sb.append("  mPreviousProcessVisibleTime: ");
11415            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11416            pw.println(sb);
11417        }
11418        if (mHeavyWeightProcess != null && (dumpPackage == null
11419                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11420            if (needSep) {
11421                pw.println();
11422                needSep = false;
11423            }
11424            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11425        }
11426        if (dumpPackage == null) {
11427            pw.println("  mConfiguration: " + mConfiguration);
11428        }
11429        if (dumpAll) {
11430            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11431            if (mCompatModePackages.getPackages().size() > 0) {
11432                boolean printed = false;
11433                for (Map.Entry<String, Integer> entry
11434                        : mCompatModePackages.getPackages().entrySet()) {
11435                    String pkg = entry.getKey();
11436                    int mode = entry.getValue();
11437                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11438                        continue;
11439                    }
11440                    if (!printed) {
11441                        pw.println("  mScreenCompatPackages:");
11442                        printed = true;
11443                    }
11444                    pw.print("    "); pw.print(pkg); pw.print(": ");
11445                            pw.print(mode); pw.println();
11446                }
11447            }
11448        }
11449        if (dumpPackage == null) {
11450            if (mSleeping || mWentToSleep || mLockScreenShown) {
11451                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11452                        + " mLockScreenShown " + mLockScreenShown);
11453            }
11454            if (mShuttingDown || mRunningVoice) {
11455                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11456            }
11457        }
11458        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11459                || mOrigWaitForDebugger) {
11460            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11461                    || dumpPackage.equals(mOrigDebugApp)) {
11462                if (needSep) {
11463                    pw.println();
11464                    needSep = false;
11465                }
11466                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11467                        + " mDebugTransient=" + mDebugTransient
11468                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11469            }
11470        }
11471        if (mOpenGlTraceApp != null) {
11472            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11473                if (needSep) {
11474                    pw.println();
11475                    needSep = false;
11476                }
11477                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11478            }
11479        }
11480        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11481                || mProfileFd != null) {
11482            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11483                if (needSep) {
11484                    pw.println();
11485                    needSep = false;
11486                }
11487                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11488                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11489                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11490                        + mAutoStopProfiler);
11491            }
11492        }
11493        if (dumpPackage == null) {
11494            if (mAlwaysFinishActivities || mController != null) {
11495                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11496                        + " mController=" + mController);
11497            }
11498            if (dumpAll) {
11499                pw.println("  Total persistent processes: " + numPers);
11500                pw.println("  mProcessesReady=" + mProcessesReady
11501                        + " mSystemReady=" + mSystemReady);
11502                pw.println("  mBooting=" + mBooting
11503                        + " mBooted=" + mBooted
11504                        + " mFactoryTest=" + mFactoryTest);
11505                pw.print("  mLastPowerCheckRealtime=");
11506                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11507                        pw.println("");
11508                pw.print("  mLastPowerCheckUptime=");
11509                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11510                        pw.println("");
11511                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11512                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11513                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11514                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11515                        + " (" + mLruProcesses.size() + " total)"
11516                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11517                        + " mNumServiceProcs=" + mNumServiceProcs
11518                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11519                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11520                        + " mLastMemoryLevel" + mLastMemoryLevel
11521                        + " mLastNumProcesses" + mLastNumProcesses);
11522                long now = SystemClock.uptimeMillis();
11523                pw.print("  mLastIdleTime=");
11524                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11525                        pw.print(" mLowRamSinceLastIdle=");
11526                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11527                        pw.println();
11528            }
11529        }
11530
11531        if (!printedAnything) {
11532            pw.println("  (nothing)");
11533        }
11534    }
11535
11536    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11537            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11538        if (mProcessesToGc.size() > 0) {
11539            boolean printed = false;
11540            long now = SystemClock.uptimeMillis();
11541            for (int i=0; i<mProcessesToGc.size(); i++) {
11542                ProcessRecord proc = mProcessesToGc.get(i);
11543                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11544                    continue;
11545                }
11546                if (!printed) {
11547                    if (needSep) pw.println();
11548                    needSep = true;
11549                    pw.println("  Processes that are waiting to GC:");
11550                    printed = true;
11551                }
11552                pw.print("    Process "); pw.println(proc);
11553                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11554                        pw.print(", last gced=");
11555                        pw.print(now-proc.lastRequestedGc);
11556                        pw.print(" ms ago, last lowMem=");
11557                        pw.print(now-proc.lastLowMemory);
11558                        pw.println(" ms ago");
11559
11560            }
11561        }
11562        return needSep;
11563    }
11564
11565    void printOomLevel(PrintWriter pw, String name, int adj) {
11566        pw.print("    ");
11567        if (adj >= 0) {
11568            pw.print(' ');
11569            if (adj < 10) pw.print(' ');
11570        } else {
11571            if (adj > -10) pw.print(' ');
11572        }
11573        pw.print(adj);
11574        pw.print(": ");
11575        pw.print(name);
11576        pw.print(" (");
11577        pw.print(mProcessList.getMemLevel(adj)/1024);
11578        pw.println(" kB)");
11579    }
11580
11581    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11582            int opti, boolean dumpAll) {
11583        boolean needSep = false;
11584
11585        if (mLruProcesses.size() > 0) {
11586            if (needSep) pw.println();
11587            needSep = true;
11588            pw.println("  OOM levels:");
11589            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11590            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11591            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11592            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11593            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11594            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11595            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11596            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11597            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11598            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11599            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11600            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11601            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11602
11603            if (needSep) pw.println();
11604            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11605                    pw.print(" total, non-act at ");
11606                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11607                    pw.print(", non-svc at ");
11608                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11609                    pw.println("):");
11610            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11611            needSep = true;
11612        }
11613
11614        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11615
11616        pw.println();
11617        pw.println("  mHomeProcess: " + mHomeProcess);
11618        pw.println("  mPreviousProcess: " + mPreviousProcess);
11619        if (mHeavyWeightProcess != null) {
11620            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11621        }
11622
11623        return true;
11624    }
11625
11626    /**
11627     * There are three ways to call this:
11628     *  - no provider specified: dump all the providers
11629     *  - a flattened component name that matched an existing provider was specified as the
11630     *    first arg: dump that one provider
11631     *  - the first arg isn't the flattened component name of an existing provider:
11632     *    dump all providers whose component contains the first arg as a substring
11633     */
11634    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11635            int opti, boolean dumpAll) {
11636        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11637    }
11638
11639    static class ItemMatcher {
11640        ArrayList<ComponentName> components;
11641        ArrayList<String> strings;
11642        ArrayList<Integer> objects;
11643        boolean all;
11644
11645        ItemMatcher() {
11646            all = true;
11647        }
11648
11649        void build(String name) {
11650            ComponentName componentName = ComponentName.unflattenFromString(name);
11651            if (componentName != null) {
11652                if (components == null) {
11653                    components = new ArrayList<ComponentName>();
11654                }
11655                components.add(componentName);
11656                all = false;
11657            } else {
11658                int objectId = 0;
11659                // Not a '/' separated full component name; maybe an object ID?
11660                try {
11661                    objectId = Integer.parseInt(name, 16);
11662                    if (objects == null) {
11663                        objects = new ArrayList<Integer>();
11664                    }
11665                    objects.add(objectId);
11666                    all = false;
11667                } catch (RuntimeException e) {
11668                    // Not an integer; just do string match.
11669                    if (strings == null) {
11670                        strings = new ArrayList<String>();
11671                    }
11672                    strings.add(name);
11673                    all = false;
11674                }
11675            }
11676        }
11677
11678        int build(String[] args, int opti) {
11679            for (; opti<args.length; opti++) {
11680                String name = args[opti];
11681                if ("--".equals(name)) {
11682                    return opti+1;
11683                }
11684                build(name);
11685            }
11686            return opti;
11687        }
11688
11689        boolean match(Object object, ComponentName comp) {
11690            if (all) {
11691                return true;
11692            }
11693            if (components != null) {
11694                for (int i=0; i<components.size(); i++) {
11695                    if (components.get(i).equals(comp)) {
11696                        return true;
11697                    }
11698                }
11699            }
11700            if (objects != null) {
11701                for (int i=0; i<objects.size(); i++) {
11702                    if (System.identityHashCode(object) == objects.get(i)) {
11703                        return true;
11704                    }
11705                }
11706            }
11707            if (strings != null) {
11708                String flat = comp.flattenToString();
11709                for (int i=0; i<strings.size(); i++) {
11710                    if (flat.contains(strings.get(i))) {
11711                        return true;
11712                    }
11713                }
11714            }
11715            return false;
11716        }
11717    }
11718
11719    /**
11720     * There are three things that cmd can be:
11721     *  - a flattened component name that matches an existing activity
11722     *  - the cmd arg isn't the flattened component name of an existing activity:
11723     *    dump all activity whose component contains the cmd as a substring
11724     *  - A hex number of the ActivityRecord object instance.
11725     */
11726    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11727            int opti, boolean dumpAll) {
11728        ArrayList<ActivityRecord> activities;
11729
11730        synchronized (this) {
11731            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11732        }
11733
11734        if (activities.size() <= 0) {
11735            return false;
11736        }
11737
11738        String[] newArgs = new String[args.length - opti];
11739        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11740
11741        TaskRecord lastTask = null;
11742        boolean needSep = false;
11743        for (int i=activities.size()-1; i>=0; i--) {
11744            ActivityRecord r = activities.get(i);
11745            if (needSep) {
11746                pw.println();
11747            }
11748            needSep = true;
11749            synchronized (this) {
11750                if (lastTask != r.task) {
11751                    lastTask = r.task;
11752                    pw.print("TASK "); pw.print(lastTask.affinity);
11753                            pw.print(" id="); pw.println(lastTask.taskId);
11754                    if (dumpAll) {
11755                        lastTask.dump(pw, "  ");
11756                    }
11757                }
11758            }
11759            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11760        }
11761        return true;
11762    }
11763
11764    /**
11765     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11766     * there is a thread associated with the activity.
11767     */
11768    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11769            final ActivityRecord r, String[] args, boolean dumpAll) {
11770        String innerPrefix = prefix + "  ";
11771        synchronized (this) {
11772            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11773                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11774                    pw.print(" pid=");
11775                    if (r.app != null) pw.println(r.app.pid);
11776                    else pw.println("(not running)");
11777            if (dumpAll) {
11778                r.dump(pw, innerPrefix);
11779            }
11780        }
11781        if (r.app != null && r.app.thread != null) {
11782            // flush anything that is already in the PrintWriter since the thread is going
11783            // to write to the file descriptor directly
11784            pw.flush();
11785            try {
11786                TransferPipe tp = new TransferPipe();
11787                try {
11788                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11789                            r.appToken, innerPrefix, args);
11790                    tp.go(fd);
11791                } finally {
11792                    tp.kill();
11793                }
11794            } catch (IOException e) {
11795                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11796            } catch (RemoteException e) {
11797                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11798            }
11799        }
11800    }
11801
11802    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11803            int opti, boolean dumpAll, String dumpPackage) {
11804        boolean needSep = false;
11805        boolean onlyHistory = false;
11806        boolean printedAnything = false;
11807
11808        if ("history".equals(dumpPackage)) {
11809            if (opti < args.length && "-s".equals(args[opti])) {
11810                dumpAll = false;
11811            }
11812            onlyHistory = true;
11813            dumpPackage = null;
11814        }
11815
11816        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11817        if (!onlyHistory && dumpAll) {
11818            if (mRegisteredReceivers.size() > 0) {
11819                boolean printed = false;
11820                Iterator it = mRegisteredReceivers.values().iterator();
11821                while (it.hasNext()) {
11822                    ReceiverList r = (ReceiverList)it.next();
11823                    if (dumpPackage != null && (r.app == null ||
11824                            !dumpPackage.equals(r.app.info.packageName))) {
11825                        continue;
11826                    }
11827                    if (!printed) {
11828                        pw.println("  Registered Receivers:");
11829                        needSep = true;
11830                        printed = true;
11831                        printedAnything = true;
11832                    }
11833                    pw.print("  * "); pw.println(r);
11834                    r.dump(pw, "    ");
11835                }
11836            }
11837
11838            if (mReceiverResolver.dump(pw, needSep ?
11839                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11840                    "    ", dumpPackage, false)) {
11841                needSep = true;
11842                printedAnything = true;
11843            }
11844        }
11845
11846        for (BroadcastQueue q : mBroadcastQueues) {
11847            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11848            printedAnything |= needSep;
11849        }
11850
11851        needSep = true;
11852
11853        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11854            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11855                if (needSep) {
11856                    pw.println();
11857                }
11858                needSep = true;
11859                printedAnything = true;
11860                pw.print("  Sticky broadcasts for user ");
11861                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11862                StringBuilder sb = new StringBuilder(128);
11863                for (Map.Entry<String, ArrayList<Intent>> ent
11864                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11865                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11866                    if (dumpAll) {
11867                        pw.println(":");
11868                        ArrayList<Intent> intents = ent.getValue();
11869                        final int N = intents.size();
11870                        for (int i=0; i<N; i++) {
11871                            sb.setLength(0);
11872                            sb.append("    Intent: ");
11873                            intents.get(i).toShortString(sb, false, true, false, false);
11874                            pw.println(sb.toString());
11875                            Bundle bundle = intents.get(i).getExtras();
11876                            if (bundle != null) {
11877                                pw.print("      ");
11878                                pw.println(bundle.toString());
11879                            }
11880                        }
11881                    } else {
11882                        pw.println("");
11883                    }
11884                }
11885            }
11886        }
11887
11888        if (!onlyHistory && dumpAll) {
11889            pw.println();
11890            for (BroadcastQueue queue : mBroadcastQueues) {
11891                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11892                        + queue.mBroadcastsScheduled);
11893            }
11894            pw.println("  mHandler:");
11895            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11896            needSep = true;
11897            printedAnything = true;
11898        }
11899
11900        if (!printedAnything) {
11901            pw.println("  (nothing)");
11902        }
11903    }
11904
11905    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11906            int opti, boolean dumpAll, String dumpPackage) {
11907        boolean needSep;
11908        boolean printedAnything = false;
11909
11910        ItemMatcher matcher = new ItemMatcher();
11911        matcher.build(args, opti);
11912
11913        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11914
11915        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11916        printedAnything |= needSep;
11917
11918        if (mLaunchingProviders.size() > 0) {
11919            boolean printed = false;
11920            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11921                ContentProviderRecord r = mLaunchingProviders.get(i);
11922                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11923                    continue;
11924                }
11925                if (!printed) {
11926                    if (needSep) pw.println();
11927                    needSep = true;
11928                    pw.println("  Launching content providers:");
11929                    printed = true;
11930                    printedAnything = true;
11931                }
11932                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11933                        pw.println(r);
11934            }
11935        }
11936
11937        if (mGrantedUriPermissions.size() > 0) {
11938            boolean printed = false;
11939            int dumpUid = -2;
11940            if (dumpPackage != null) {
11941                try {
11942                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11943                } catch (NameNotFoundException e) {
11944                    dumpUid = -1;
11945                }
11946            }
11947            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11948                int uid = mGrantedUriPermissions.keyAt(i);
11949                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11950                    continue;
11951                }
11952                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11953                if (!printed) {
11954                    if (needSep) pw.println();
11955                    needSep = true;
11956                    pw.println("  Granted Uri Permissions:");
11957                    printed = true;
11958                    printedAnything = true;
11959                }
11960                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11961                for (UriPermission perm : perms.values()) {
11962                    pw.print("    "); pw.println(perm);
11963                    if (dumpAll) {
11964                        perm.dump(pw, "      ");
11965                    }
11966                }
11967            }
11968        }
11969
11970        if (!printedAnything) {
11971            pw.println("  (nothing)");
11972        }
11973    }
11974
11975    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11976            int opti, boolean dumpAll, String dumpPackage) {
11977        boolean printed = false;
11978
11979        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11980
11981        if (mIntentSenderRecords.size() > 0) {
11982            Iterator<WeakReference<PendingIntentRecord>> it
11983                    = mIntentSenderRecords.values().iterator();
11984            while (it.hasNext()) {
11985                WeakReference<PendingIntentRecord> ref = it.next();
11986                PendingIntentRecord rec = ref != null ? ref.get(): null;
11987                if (dumpPackage != null && (rec == null
11988                        || !dumpPackage.equals(rec.key.packageName))) {
11989                    continue;
11990                }
11991                printed = true;
11992                if (rec != null) {
11993                    pw.print("  * "); pw.println(rec);
11994                    if (dumpAll) {
11995                        rec.dump(pw, "    ");
11996                    }
11997                } else {
11998                    pw.print("  * "); pw.println(ref);
11999                }
12000            }
12001        }
12002
12003        if (!printed) {
12004            pw.println("  (nothing)");
12005        }
12006    }
12007
12008    private static final int dumpProcessList(PrintWriter pw,
12009            ActivityManagerService service, List list,
12010            String prefix, String normalLabel, String persistentLabel,
12011            String dumpPackage) {
12012        int numPers = 0;
12013        final int N = list.size()-1;
12014        for (int i=N; i>=0; i--) {
12015            ProcessRecord r = (ProcessRecord)list.get(i);
12016            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12017                continue;
12018            }
12019            pw.println(String.format("%s%s #%2d: %s",
12020                    prefix, (r.persistent ? persistentLabel : normalLabel),
12021                    i, r.toString()));
12022            if (r.persistent) {
12023                numPers++;
12024            }
12025        }
12026        return numPers;
12027    }
12028
12029    private static final boolean dumpProcessOomList(PrintWriter pw,
12030            ActivityManagerService service, List<ProcessRecord> origList,
12031            String prefix, String normalLabel, String persistentLabel,
12032            boolean inclDetails, String dumpPackage) {
12033
12034        ArrayList<Pair<ProcessRecord, Integer>> list
12035                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12036        for (int i=0; i<origList.size(); i++) {
12037            ProcessRecord r = origList.get(i);
12038            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12039                continue;
12040            }
12041            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12042        }
12043
12044        if (list.size() <= 0) {
12045            return false;
12046        }
12047
12048        Comparator<Pair<ProcessRecord, Integer>> comparator
12049                = new Comparator<Pair<ProcessRecord, Integer>>() {
12050            @Override
12051            public int compare(Pair<ProcessRecord, Integer> object1,
12052                    Pair<ProcessRecord, Integer> object2) {
12053                if (object1.first.setAdj != object2.first.setAdj) {
12054                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12055                }
12056                if (object1.second.intValue() != object2.second.intValue()) {
12057                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12058                }
12059                return 0;
12060            }
12061        };
12062
12063        Collections.sort(list, comparator);
12064
12065        final long curRealtime = SystemClock.elapsedRealtime();
12066        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12067        final long curUptime = SystemClock.uptimeMillis();
12068        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12069
12070        for (int i=list.size()-1; i>=0; i--) {
12071            ProcessRecord r = list.get(i).first;
12072            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12073            char schedGroup;
12074            switch (r.setSchedGroup) {
12075                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12076                    schedGroup = 'B';
12077                    break;
12078                case Process.THREAD_GROUP_DEFAULT:
12079                    schedGroup = 'F';
12080                    break;
12081                default:
12082                    schedGroup = '?';
12083                    break;
12084            }
12085            char foreground;
12086            if (r.foregroundActivities) {
12087                foreground = 'A';
12088            } else if (r.foregroundServices) {
12089                foreground = 'S';
12090            } else {
12091                foreground = ' ';
12092            }
12093            String procState = ProcessList.makeProcStateString(r.curProcState);
12094            pw.print(prefix);
12095            pw.print(r.persistent ? persistentLabel : normalLabel);
12096            pw.print(" #");
12097            int num = (origList.size()-1)-list.get(i).second;
12098            if (num < 10) pw.print(' ');
12099            pw.print(num);
12100            pw.print(": ");
12101            pw.print(oomAdj);
12102            pw.print(' ');
12103            pw.print(schedGroup);
12104            pw.print('/');
12105            pw.print(foreground);
12106            pw.print('/');
12107            pw.print(procState);
12108            pw.print(" trm:");
12109            if (r.trimMemoryLevel < 10) pw.print(' ');
12110            pw.print(r.trimMemoryLevel);
12111            pw.print(' ');
12112            pw.print(r.toShortString());
12113            pw.print(" (");
12114            pw.print(r.adjType);
12115            pw.println(')');
12116            if (r.adjSource != null || r.adjTarget != null) {
12117                pw.print(prefix);
12118                pw.print("    ");
12119                if (r.adjTarget instanceof ComponentName) {
12120                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12121                } else if (r.adjTarget != null) {
12122                    pw.print(r.adjTarget.toString());
12123                } else {
12124                    pw.print("{null}");
12125                }
12126                pw.print("<=");
12127                if (r.adjSource instanceof ProcessRecord) {
12128                    pw.print("Proc{");
12129                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12130                    pw.println("}");
12131                } else if (r.adjSource != null) {
12132                    pw.println(r.adjSource.toString());
12133                } else {
12134                    pw.println("{null}");
12135                }
12136            }
12137            if (inclDetails) {
12138                pw.print(prefix);
12139                pw.print("    ");
12140                pw.print("oom: max="); pw.print(r.maxAdj);
12141                pw.print(" curRaw="); pw.print(r.curRawAdj);
12142                pw.print(" setRaw="); pw.print(r.setRawAdj);
12143                pw.print(" cur="); pw.print(r.curAdj);
12144                pw.print(" set="); pw.println(r.setAdj);
12145                pw.print(prefix);
12146                pw.print("    ");
12147                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12148                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12149                pw.print(" lastPss="); pw.print(r.lastPss);
12150                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12151                pw.print(prefix);
12152                pw.print("    ");
12153                pw.print("keeping="); pw.print(r.keeping);
12154                pw.print(" cached="); pw.print(r.cached);
12155                pw.print(" empty="); pw.print(r.empty);
12156                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12157
12158                if (!r.keeping) {
12159                    if (r.lastWakeTime != 0) {
12160                        long wtime;
12161                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12162                        synchronized (stats) {
12163                            wtime = stats.getProcessWakeTime(r.info.uid,
12164                                    r.pid, curRealtime);
12165                        }
12166                        long timeUsed = wtime - r.lastWakeTime;
12167                        pw.print(prefix);
12168                        pw.print("    ");
12169                        pw.print("keep awake over ");
12170                        TimeUtils.formatDuration(realtimeSince, pw);
12171                        pw.print(" used ");
12172                        TimeUtils.formatDuration(timeUsed, pw);
12173                        pw.print(" (");
12174                        pw.print((timeUsed*100)/realtimeSince);
12175                        pw.println("%)");
12176                    }
12177                    if (r.lastCpuTime != 0) {
12178                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12179                        pw.print(prefix);
12180                        pw.print("    ");
12181                        pw.print("run cpu over ");
12182                        TimeUtils.formatDuration(uptimeSince, pw);
12183                        pw.print(" used ");
12184                        TimeUtils.formatDuration(timeUsed, pw);
12185                        pw.print(" (");
12186                        pw.print((timeUsed*100)/uptimeSince);
12187                        pw.println("%)");
12188                    }
12189                }
12190            }
12191        }
12192        return true;
12193    }
12194
12195    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12196        ArrayList<ProcessRecord> procs;
12197        synchronized (this) {
12198            if (args != null && args.length > start
12199                    && args[start].charAt(0) != '-') {
12200                procs = new ArrayList<ProcessRecord>();
12201                int pid = -1;
12202                try {
12203                    pid = Integer.parseInt(args[start]);
12204                } catch (NumberFormatException e) {
12205                }
12206                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12207                    ProcessRecord proc = mLruProcesses.get(i);
12208                    if (proc.pid == pid) {
12209                        procs.add(proc);
12210                    } else if (proc.processName.equals(args[start])) {
12211                        procs.add(proc);
12212                    }
12213                }
12214                if (procs.size() <= 0) {
12215                    return null;
12216                }
12217            } else {
12218                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12219            }
12220        }
12221        return procs;
12222    }
12223
12224    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12225            PrintWriter pw, String[] args) {
12226        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12227        if (procs == null) {
12228            pw.println("No process found for: " + args[0]);
12229            return;
12230        }
12231
12232        long uptime = SystemClock.uptimeMillis();
12233        long realtime = SystemClock.elapsedRealtime();
12234        pw.println("Applications Graphics Acceleration Info:");
12235        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12236
12237        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12238            ProcessRecord r = procs.get(i);
12239            if (r.thread != null) {
12240                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12241                pw.flush();
12242                try {
12243                    TransferPipe tp = new TransferPipe();
12244                    try {
12245                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12246                        tp.go(fd);
12247                    } finally {
12248                        tp.kill();
12249                    }
12250                } catch (IOException e) {
12251                    pw.println("Failure while dumping the app: " + r);
12252                    pw.flush();
12253                } catch (RemoteException e) {
12254                    pw.println("Got a RemoteException while dumping the app " + r);
12255                    pw.flush();
12256                }
12257            }
12258        }
12259    }
12260
12261    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12262        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12263        if (procs == null) {
12264            pw.println("No process found for: " + args[0]);
12265            return;
12266        }
12267
12268        pw.println("Applications Database Info:");
12269
12270        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12271            ProcessRecord r = procs.get(i);
12272            if (r.thread != null) {
12273                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12274                pw.flush();
12275                try {
12276                    TransferPipe tp = new TransferPipe();
12277                    try {
12278                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12279                        tp.go(fd);
12280                    } finally {
12281                        tp.kill();
12282                    }
12283                } catch (IOException e) {
12284                    pw.println("Failure while dumping the app: " + r);
12285                    pw.flush();
12286                } catch (RemoteException e) {
12287                    pw.println("Got a RemoteException while dumping the app " + r);
12288                    pw.flush();
12289                }
12290            }
12291        }
12292    }
12293
12294    final static class MemItem {
12295        final boolean isProc;
12296        final String label;
12297        final String shortLabel;
12298        final long pss;
12299        final int id;
12300        final boolean hasActivities;
12301        ArrayList<MemItem> subitems;
12302
12303        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12304                boolean _hasActivities) {
12305            isProc = true;
12306            label = _label;
12307            shortLabel = _shortLabel;
12308            pss = _pss;
12309            id = _id;
12310            hasActivities = _hasActivities;
12311        }
12312
12313        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12314            isProc = false;
12315            label = _label;
12316            shortLabel = _shortLabel;
12317            pss = _pss;
12318            id = _id;
12319            hasActivities = false;
12320        }
12321    }
12322
12323    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12324            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12325        if (sort && !isCompact) {
12326            Collections.sort(items, new Comparator<MemItem>() {
12327                @Override
12328                public int compare(MemItem lhs, MemItem rhs) {
12329                    if (lhs.pss < rhs.pss) {
12330                        return 1;
12331                    } else if (lhs.pss > rhs.pss) {
12332                        return -1;
12333                    }
12334                    return 0;
12335                }
12336            });
12337        }
12338
12339        for (int i=0; i<items.size(); i++) {
12340            MemItem mi = items.get(i);
12341            if (!isCompact) {
12342                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12343            } else if (mi.isProc) {
12344                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12345                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12346                pw.println(mi.hasActivities ? ",a" : ",e");
12347            } else {
12348                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12349                pw.println(mi.pss);
12350            }
12351            if (mi.subitems != null) {
12352                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12353                        true, isCompact);
12354            }
12355        }
12356    }
12357
12358    // These are in KB.
12359    static final long[] DUMP_MEM_BUCKETS = new long[] {
12360        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12361        120*1024, 160*1024, 200*1024,
12362        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12363        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12364    };
12365
12366    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12367            boolean stackLike) {
12368        int start = label.lastIndexOf('.');
12369        if (start >= 0) start++;
12370        else start = 0;
12371        int end = label.length();
12372        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12373            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12374                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12375                out.append(bucket);
12376                out.append(stackLike ? "MB." : "MB ");
12377                out.append(label, start, end);
12378                return;
12379            }
12380        }
12381        out.append(memKB/1024);
12382        out.append(stackLike ? "MB." : "MB ");
12383        out.append(label, start, end);
12384    }
12385
12386    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12387            ProcessList.NATIVE_ADJ,
12388            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12389            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12390            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12391            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12392            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12393    };
12394    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12395            "Native",
12396            "System", "Persistent", "Foreground",
12397            "Visible", "Perceptible",
12398            "Heavy Weight", "Backup",
12399            "A Services", "Home",
12400            "Previous", "B Services", "Cached"
12401    };
12402    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12403            "native",
12404            "sys", "pers", "fore",
12405            "vis", "percept",
12406            "heavy", "backup",
12407            "servicea", "home",
12408            "prev", "serviceb", "cached"
12409    };
12410
12411    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12412            long realtime, boolean isCheckinRequest, boolean isCompact) {
12413        if (isCheckinRequest || isCompact) {
12414            // short checkin version
12415            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12416        } else {
12417            pw.println("Applications Memory Usage (kB):");
12418            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12419        }
12420    }
12421
12422    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12423            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12424        boolean dumpDetails = false;
12425        boolean dumpFullDetails = false;
12426        boolean dumpDalvik = false;
12427        boolean oomOnly = false;
12428        boolean isCompact = false;
12429        boolean localOnly = false;
12430
12431        int opti = 0;
12432        while (opti < args.length) {
12433            String opt = args[opti];
12434            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12435                break;
12436            }
12437            opti++;
12438            if ("-a".equals(opt)) {
12439                dumpDetails = true;
12440                dumpFullDetails = true;
12441                dumpDalvik = true;
12442            } else if ("-d".equals(opt)) {
12443                dumpDalvik = true;
12444            } else if ("-c".equals(opt)) {
12445                isCompact = true;
12446            } else if ("--oom".equals(opt)) {
12447                oomOnly = true;
12448            } else if ("--local".equals(opt)) {
12449                localOnly = true;
12450            } else if ("-h".equals(opt)) {
12451                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12452                pw.println("  -a: include all available information for each process.");
12453                pw.println("  -d: include dalvik details when dumping process details.");
12454                pw.println("  -c: dump in a compact machine-parseable representation.");
12455                pw.println("  --oom: only show processes organized by oom adj.");
12456                pw.println("  --local: only collect details locally, don't call process.");
12457                pw.println("If [process] is specified it can be the name or ");
12458                pw.println("pid of a specific process to dump.");
12459                return;
12460            } else {
12461                pw.println("Unknown argument: " + opt + "; use -h for help");
12462            }
12463        }
12464
12465        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12466        long uptime = SystemClock.uptimeMillis();
12467        long realtime = SystemClock.elapsedRealtime();
12468        final long[] tmpLong = new long[1];
12469
12470        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12471        if (procs == null) {
12472            // No Java processes.  Maybe they want to print a native process.
12473            if (args != null && args.length > opti
12474                    && args[opti].charAt(0) != '-') {
12475                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12476                        = new ArrayList<ProcessCpuTracker.Stats>();
12477                updateCpuStatsNow();
12478                int findPid = -1;
12479                try {
12480                    findPid = Integer.parseInt(args[opti]);
12481                } catch (NumberFormatException e) {
12482                }
12483                synchronized (mProcessCpuThread) {
12484                    final int N = mProcessCpuTracker.countStats();
12485                    for (int i=0; i<N; i++) {
12486                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12487                        if (st.pid == findPid || (st.baseName != null
12488                                && st.baseName.equals(args[opti]))) {
12489                            nativeProcs.add(st);
12490                        }
12491                    }
12492                }
12493                if (nativeProcs.size() > 0) {
12494                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12495                            isCompact);
12496                    Debug.MemoryInfo mi = null;
12497                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12498                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12499                        final int pid = r.pid;
12500                        if (!isCheckinRequest && dumpDetails) {
12501                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12502                        }
12503                        if (mi == null) {
12504                            mi = new Debug.MemoryInfo();
12505                        }
12506                        if (dumpDetails || (!brief && !oomOnly)) {
12507                            Debug.getMemoryInfo(pid, mi);
12508                        } else {
12509                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12510                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12511                        }
12512                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12513                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12514                        if (isCheckinRequest) {
12515                            pw.println();
12516                        }
12517                    }
12518                    return;
12519                }
12520            }
12521            pw.println("No process found for: " + args[opti]);
12522            return;
12523        }
12524
12525        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12526            dumpDetails = true;
12527        }
12528
12529        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12530
12531        String[] innerArgs = new String[args.length-opti];
12532        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12533
12534        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12535        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12536        long nativePss=0, dalvikPss=0, otherPss=0;
12537        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12538
12539        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12540        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12541                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12542
12543        long totalPss = 0;
12544        long cachedPss = 0;
12545
12546        Debug.MemoryInfo mi = null;
12547        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12548            final ProcessRecord r = procs.get(i);
12549            final IApplicationThread thread;
12550            final int pid;
12551            final int oomAdj;
12552            final boolean hasActivities;
12553            synchronized (this) {
12554                thread = r.thread;
12555                pid = r.pid;
12556                oomAdj = r.getSetAdjWithServices();
12557                hasActivities = r.activities.size() > 0;
12558            }
12559            if (thread != null) {
12560                if (!isCheckinRequest && dumpDetails) {
12561                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12562                }
12563                if (mi == null) {
12564                    mi = new Debug.MemoryInfo();
12565                }
12566                if (dumpDetails || (!brief && !oomOnly)) {
12567                    Debug.getMemoryInfo(pid, mi);
12568                } else {
12569                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12570                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12571                }
12572                if (dumpDetails) {
12573                    if (localOnly) {
12574                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12575                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12576                        if (isCheckinRequest) {
12577                            pw.println();
12578                        }
12579                    } else {
12580                        try {
12581                            pw.flush();
12582                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12583                                    dumpDalvik, innerArgs);
12584                        } catch (RemoteException e) {
12585                            if (!isCheckinRequest) {
12586                                pw.println("Got RemoteException!");
12587                                pw.flush();
12588                            }
12589                        }
12590                    }
12591                }
12592
12593                final long myTotalPss = mi.getTotalPss();
12594                final long myTotalUss = mi.getTotalUss();
12595
12596                synchronized (this) {
12597                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12598                        // Record this for posterity if the process has been stable.
12599                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12600                    }
12601                }
12602
12603                if (!isCheckinRequest && mi != null) {
12604                    totalPss += myTotalPss;
12605                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12606                            (hasActivities ? " / activities)" : ")"),
12607                            r.processName, myTotalPss, pid, hasActivities);
12608                    procMems.add(pssItem);
12609                    procMemsMap.put(pid, pssItem);
12610
12611                    nativePss += mi.nativePss;
12612                    dalvikPss += mi.dalvikPss;
12613                    otherPss += mi.otherPss;
12614                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12615                        long mem = mi.getOtherPss(j);
12616                        miscPss[j] += mem;
12617                        otherPss -= mem;
12618                    }
12619
12620                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12621                        cachedPss += myTotalPss;
12622                    }
12623
12624                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12625                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12626                                || oomIndex == (oomPss.length-1)) {
12627                            oomPss[oomIndex] += myTotalPss;
12628                            if (oomProcs[oomIndex] == null) {
12629                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12630                            }
12631                            oomProcs[oomIndex].add(pssItem);
12632                            break;
12633                        }
12634                    }
12635                }
12636            }
12637        }
12638
12639        long nativeProcTotalPss = 0;
12640
12641        if (!isCheckinRequest && procs.size() > 1) {
12642            // If we are showing aggregations, also look for native processes to
12643            // include so that our aggregations are more accurate.
12644            updateCpuStatsNow();
12645            synchronized (mProcessCpuThread) {
12646                final int N = mProcessCpuTracker.countStats();
12647                for (int i=0; i<N; i++) {
12648                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12649                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12650                        if (mi == null) {
12651                            mi = new Debug.MemoryInfo();
12652                        }
12653                        if (!brief && !oomOnly) {
12654                            Debug.getMemoryInfo(st.pid, mi);
12655                        } else {
12656                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12657                            mi.nativePrivateDirty = (int)tmpLong[0];
12658                        }
12659
12660                        final long myTotalPss = mi.getTotalPss();
12661                        totalPss += myTotalPss;
12662                        nativeProcTotalPss += myTotalPss;
12663
12664                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12665                                st.name, myTotalPss, st.pid, false);
12666                        procMems.add(pssItem);
12667
12668                        nativePss += mi.nativePss;
12669                        dalvikPss += mi.dalvikPss;
12670                        otherPss += mi.otherPss;
12671                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12672                            long mem = mi.getOtherPss(j);
12673                            miscPss[j] += mem;
12674                            otherPss -= mem;
12675                        }
12676                        oomPss[0] += myTotalPss;
12677                        if (oomProcs[0] == null) {
12678                            oomProcs[0] = new ArrayList<MemItem>();
12679                        }
12680                        oomProcs[0].add(pssItem);
12681                    }
12682                }
12683            }
12684
12685            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12686
12687            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12688            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12689            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12690            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12691                String label = Debug.MemoryInfo.getOtherLabel(j);
12692                catMems.add(new MemItem(label, label, miscPss[j], j));
12693            }
12694
12695            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12696            for (int j=0; j<oomPss.length; j++) {
12697                if (oomPss[j] != 0) {
12698                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12699                            : DUMP_MEM_OOM_LABEL[j];
12700                    MemItem item = new MemItem(label, label, oomPss[j],
12701                            DUMP_MEM_OOM_ADJ[j]);
12702                    item.subitems = oomProcs[j];
12703                    oomMems.add(item);
12704                }
12705            }
12706
12707            if (!brief && !oomOnly && !isCompact) {
12708                pw.println();
12709                pw.println("Total PSS by process:");
12710                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12711                pw.println();
12712            }
12713            if (!isCompact) {
12714                pw.println("Total PSS by OOM adjustment:");
12715            }
12716            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12717            if (!brief && !oomOnly) {
12718                PrintWriter out = categoryPw != null ? categoryPw : pw;
12719                if (!isCompact) {
12720                    out.println();
12721                    out.println("Total PSS by category:");
12722                }
12723                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12724            }
12725            if (!isCompact) {
12726                pw.println();
12727            }
12728            MemInfoReader memInfo = new MemInfoReader();
12729            memInfo.readMemInfo();
12730            if (nativeProcTotalPss > 0) {
12731                synchronized (this) {
12732                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12733                            memInfo.getFreeSizeKb(),
12734                            memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(),
12735                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12736                            nativeProcTotalPss);
12737                }
12738            }
12739            if (!brief) {
12740                if (!isCompact) {
12741                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12742                    pw.print(" kB (status ");
12743                    switch (mLastMemoryLevel) {
12744                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12745                            pw.println("normal)");
12746                            break;
12747                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12748                            pw.println("moderate)");
12749                            break;
12750                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12751                            pw.println("low)");
12752                            break;
12753                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12754                            pw.println("critical)");
12755                            break;
12756                        default:
12757                            pw.print(mLastMemoryLevel);
12758                            pw.println(")");
12759                            break;
12760                    }
12761                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12762                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12763                            pw.print(cachedPss); pw.print(" cached pss + ");
12764                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12765                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12766                } else {
12767                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12768                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12769                            + memInfo.getFreeSizeKb()); pw.print(",");
12770                    pw.println(totalPss - cachedPss);
12771                }
12772            }
12773            if (!isCompact) {
12774                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12775                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12776                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12777                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12778                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12779                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12780                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12781                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12782                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12783                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12784                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12785            }
12786            if (!brief) {
12787                if (memInfo.getZramTotalSizeKb() != 0) {
12788                    if (!isCompact) {
12789                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12790                                pw.print(" kB physical used for ");
12791                                pw.print(memInfo.getSwapTotalSizeKb()
12792                                        - memInfo.getSwapFreeSizeKb());
12793                                pw.print(" kB in swap (");
12794                                pw.print(memInfo.getSwapTotalSizeKb());
12795                                pw.println(" kB total swap)");
12796                    } else {
12797                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12798                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12799                                pw.println(memInfo.getSwapFreeSizeKb());
12800                    }
12801                }
12802                final int[] SINGLE_LONG_FORMAT = new int[] {
12803                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12804                };
12805                long[] longOut = new long[1];
12806                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12807                        SINGLE_LONG_FORMAT, null, longOut, null);
12808                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12809                longOut[0] = 0;
12810                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12811                        SINGLE_LONG_FORMAT, null, longOut, null);
12812                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12813                longOut[0] = 0;
12814                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12815                        SINGLE_LONG_FORMAT, null, longOut, null);
12816                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12817                longOut[0] = 0;
12818                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12819                        SINGLE_LONG_FORMAT, null, longOut, null);
12820                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12821                if (!isCompact) {
12822                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12823                        pw.print("      KSM: "); pw.print(sharing);
12824                                pw.print(" kB saved from shared ");
12825                                pw.print(shared); pw.println(" kB");
12826                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12827                                pw.print(voltile); pw.println(" kB volatile");
12828                    }
12829                    pw.print("   Tuning: ");
12830                    pw.print(ActivityManager.staticGetMemoryClass());
12831                    pw.print(" (large ");
12832                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12833                    pw.print("), oom ");
12834                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12835                    pw.print(" kB");
12836                    pw.print(", restore limit ");
12837                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12838                    pw.print(" kB");
12839                    if (ActivityManager.isLowRamDeviceStatic()) {
12840                        pw.print(" (low-ram)");
12841                    }
12842                    if (ActivityManager.isHighEndGfx()) {
12843                        pw.print(" (high-end-gfx)");
12844                    }
12845                    pw.println();
12846                } else {
12847                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12848                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12849                    pw.println(voltile);
12850                    pw.print("tuning,");
12851                    pw.print(ActivityManager.staticGetMemoryClass());
12852                    pw.print(',');
12853                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12854                    pw.print(',');
12855                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12856                    if (ActivityManager.isLowRamDeviceStatic()) {
12857                        pw.print(",low-ram");
12858                    }
12859                    if (ActivityManager.isHighEndGfx()) {
12860                        pw.print(",high-end-gfx");
12861                    }
12862                    pw.println();
12863                }
12864            }
12865        }
12866    }
12867
12868    /**
12869     * Searches array of arguments for the specified string
12870     * @param args array of argument strings
12871     * @param value value to search for
12872     * @return true if the value is contained in the array
12873     */
12874    private static boolean scanArgs(String[] args, String value) {
12875        if (args != null) {
12876            for (String arg : args) {
12877                if (value.equals(arg)) {
12878                    return true;
12879                }
12880            }
12881        }
12882        return false;
12883    }
12884
12885    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12886            ContentProviderRecord cpr, boolean always) {
12887        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12888
12889        if (!inLaunching || always) {
12890            synchronized (cpr) {
12891                cpr.launchingApp = null;
12892                cpr.notifyAll();
12893            }
12894            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12895            String names[] = cpr.info.authority.split(";");
12896            for (int j = 0; j < names.length; j++) {
12897                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12898            }
12899        }
12900
12901        for (int i=0; i<cpr.connections.size(); i++) {
12902            ContentProviderConnection conn = cpr.connections.get(i);
12903            if (conn.waiting) {
12904                // If this connection is waiting for the provider, then we don't
12905                // need to mess with its process unless we are always removing
12906                // or for some reason the provider is not currently launching.
12907                if (inLaunching && !always) {
12908                    continue;
12909                }
12910            }
12911            ProcessRecord capp = conn.client;
12912            conn.dead = true;
12913            if (conn.stableCount > 0) {
12914                if (!capp.persistent && capp.thread != null
12915                        && capp.pid != 0
12916                        && capp.pid != MY_PID) {
12917                    killUnneededProcessLocked(capp, "depends on provider "
12918                            + cpr.name.flattenToShortString()
12919                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12920                }
12921            } else if (capp.thread != null && conn.provider.provider != null) {
12922                try {
12923                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12924                } catch (RemoteException e) {
12925                }
12926                // In the protocol here, we don't expect the client to correctly
12927                // clean up this connection, we'll just remove it.
12928                cpr.connections.remove(i);
12929                conn.client.conProviders.remove(conn);
12930            }
12931        }
12932
12933        if (inLaunching && always) {
12934            mLaunchingProviders.remove(cpr);
12935        }
12936        return inLaunching;
12937    }
12938
12939    /**
12940     * Main code for cleaning up a process when it has gone away.  This is
12941     * called both as a result of the process dying, or directly when stopping
12942     * a process when running in single process mode.
12943     */
12944    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12945            boolean restarting, boolean allowRestart, int index) {
12946        if (index >= 0) {
12947            removeLruProcessLocked(app);
12948            ProcessList.remove(app.pid);
12949        }
12950
12951        mProcessesToGc.remove(app);
12952        mPendingPssProcesses.remove(app);
12953
12954        // Dismiss any open dialogs.
12955        if (app.crashDialog != null && !app.forceCrashReport) {
12956            app.crashDialog.dismiss();
12957            app.crashDialog = null;
12958        }
12959        if (app.anrDialog != null) {
12960            app.anrDialog.dismiss();
12961            app.anrDialog = null;
12962        }
12963        if (app.waitDialog != null) {
12964            app.waitDialog.dismiss();
12965            app.waitDialog = null;
12966        }
12967
12968        app.crashing = false;
12969        app.notResponding = false;
12970
12971        app.resetPackageList(mProcessStats);
12972        app.unlinkDeathRecipient();
12973        app.makeInactive(mProcessStats);
12974        app.forcingToForeground = null;
12975        updateProcessForegroundLocked(app, false, false);
12976        app.foregroundActivities = false;
12977        app.hasShownUi = false;
12978        app.treatLikeActivity = false;
12979        app.hasAboveClient = false;
12980        app.hasClientActivities = false;
12981
12982        mServices.killServicesLocked(app, allowRestart);
12983
12984        boolean restart = false;
12985
12986        // Remove published content providers.
12987        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12988            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12989            final boolean always = app.bad || !allowRestart;
12990            if (removeDyingProviderLocked(app, cpr, always) || always) {
12991                // We left the provider in the launching list, need to
12992                // restart it.
12993                restart = true;
12994            }
12995
12996            cpr.provider = null;
12997            cpr.proc = null;
12998        }
12999        app.pubProviders.clear();
13000
13001        // Take care of any launching providers waiting for this process.
13002        if (checkAppInLaunchingProvidersLocked(app, false)) {
13003            restart = true;
13004        }
13005
13006        // Unregister from connected content providers.
13007        if (!app.conProviders.isEmpty()) {
13008            for (int i=0; i<app.conProviders.size(); i++) {
13009                ContentProviderConnection conn = app.conProviders.get(i);
13010                conn.provider.connections.remove(conn);
13011            }
13012            app.conProviders.clear();
13013        }
13014
13015        // At this point there may be remaining entries in mLaunchingProviders
13016        // where we were the only one waiting, so they are no longer of use.
13017        // Look for these and clean up if found.
13018        // XXX Commented out for now.  Trying to figure out a way to reproduce
13019        // the actual situation to identify what is actually going on.
13020        if (false) {
13021            for (int i=0; i<mLaunchingProviders.size(); i++) {
13022                ContentProviderRecord cpr = (ContentProviderRecord)
13023                        mLaunchingProviders.get(i);
13024                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13025                    synchronized (cpr) {
13026                        cpr.launchingApp = null;
13027                        cpr.notifyAll();
13028                    }
13029                }
13030            }
13031        }
13032
13033        skipCurrentReceiverLocked(app);
13034
13035        // Unregister any receivers.
13036        for (int i=app.receivers.size()-1; i>=0; i--) {
13037            removeReceiverLocked(app.receivers.valueAt(i));
13038        }
13039        app.receivers.clear();
13040
13041        // If the app is undergoing backup, tell the backup manager about it
13042        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13043            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13044                    + mBackupTarget.appInfo + " died during backup");
13045            try {
13046                IBackupManager bm = IBackupManager.Stub.asInterface(
13047                        ServiceManager.getService(Context.BACKUP_SERVICE));
13048                bm.agentDisconnected(app.info.packageName);
13049            } catch (RemoteException e) {
13050                // can't happen; backup manager is local
13051            }
13052        }
13053
13054        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13055            ProcessChangeItem item = mPendingProcessChanges.get(i);
13056            if (item.pid == app.pid) {
13057                mPendingProcessChanges.remove(i);
13058                mAvailProcessChanges.add(item);
13059            }
13060        }
13061        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13062
13063        // If the caller is restarting this app, then leave it in its
13064        // current lists and let the caller take care of it.
13065        if (restarting) {
13066            return;
13067        }
13068
13069        if (!app.persistent || app.isolated) {
13070            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13071                    "Removing non-persistent process during cleanup: " + app);
13072            mProcessNames.remove(app.processName, app.uid);
13073            mIsolatedProcesses.remove(app.uid);
13074            if (mHeavyWeightProcess == app) {
13075                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13076                        mHeavyWeightProcess.userId, 0));
13077                mHeavyWeightProcess = null;
13078            }
13079        } else if (!app.removed) {
13080            // This app is persistent, so we need to keep its record around.
13081            // If it is not already on the pending app list, add it there
13082            // and start a new process for it.
13083            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13084                mPersistentStartingProcesses.add(app);
13085                restart = true;
13086            }
13087        }
13088        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13089                "Clean-up removing on hold: " + app);
13090        mProcessesOnHold.remove(app);
13091
13092        if (app == mHomeProcess) {
13093            mHomeProcess = null;
13094        }
13095        if (app == mPreviousProcess) {
13096            mPreviousProcess = null;
13097        }
13098
13099        if (restart && !app.isolated) {
13100            // We have components that still need to be running in the
13101            // process, so re-launch it.
13102            mProcessNames.put(app.processName, app.uid, app);
13103            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13104        } else if (app.pid > 0 && app.pid != MY_PID) {
13105            // Goodbye!
13106            boolean removed;
13107            synchronized (mPidsSelfLocked) {
13108                mPidsSelfLocked.remove(app.pid);
13109                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13110            }
13111            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13112                    app.processName, app.info.uid);
13113            if (app.isolated) {
13114                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13115            }
13116            app.setPid(0);
13117        }
13118    }
13119
13120    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13121        // Look through the content providers we are waiting to have launched,
13122        // and if any run in this process then either schedule a restart of
13123        // the process or kill the client waiting for it if this process has
13124        // gone bad.
13125        int NL = mLaunchingProviders.size();
13126        boolean restart = false;
13127        for (int i=0; i<NL; i++) {
13128            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13129            if (cpr.launchingApp == app) {
13130                if (!alwaysBad && !app.bad) {
13131                    restart = true;
13132                } else {
13133                    removeDyingProviderLocked(app, cpr, true);
13134                    // cpr should have been removed from mLaunchingProviders
13135                    NL = mLaunchingProviders.size();
13136                    i--;
13137                }
13138            }
13139        }
13140        return restart;
13141    }
13142
13143    // =========================================================
13144    // SERVICES
13145    // =========================================================
13146
13147    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13148            int flags) {
13149        enforceNotIsolatedCaller("getServices");
13150        synchronized (this) {
13151            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13152        }
13153    }
13154
13155    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13156        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13157        synchronized (this) {
13158            return mServices.getRunningServiceControlPanelLocked(name);
13159        }
13160    }
13161
13162    public ComponentName startService(IApplicationThread caller, Intent service,
13163            String resolvedType, int userId) {
13164        enforceNotIsolatedCaller("startService");
13165        // Refuse possible leaked file descriptors
13166        if (service != null && service.hasFileDescriptors() == true) {
13167            throw new IllegalArgumentException("File descriptors passed in Intent");
13168        }
13169
13170        if (DEBUG_SERVICE)
13171            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13172        synchronized(this) {
13173            final int callingPid = Binder.getCallingPid();
13174            final int callingUid = Binder.getCallingUid();
13175            final long origId = Binder.clearCallingIdentity();
13176            ComponentName res = mServices.startServiceLocked(caller, service,
13177                    resolvedType, callingPid, callingUid, userId);
13178            Binder.restoreCallingIdentity(origId);
13179            return res;
13180        }
13181    }
13182
13183    ComponentName startServiceInPackage(int uid,
13184            Intent service, String resolvedType, int userId) {
13185        synchronized(this) {
13186            if (DEBUG_SERVICE)
13187                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13188            final long origId = Binder.clearCallingIdentity();
13189            ComponentName res = mServices.startServiceLocked(null, service,
13190                    resolvedType, -1, uid, userId);
13191            Binder.restoreCallingIdentity(origId);
13192            return res;
13193        }
13194    }
13195
13196    public int stopService(IApplicationThread caller, Intent service,
13197            String resolvedType, int userId) {
13198        enforceNotIsolatedCaller("stopService");
13199        // Refuse possible leaked file descriptors
13200        if (service != null && service.hasFileDescriptors() == true) {
13201            throw new IllegalArgumentException("File descriptors passed in Intent");
13202        }
13203
13204        synchronized(this) {
13205            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13206        }
13207    }
13208
13209    public IBinder peekService(Intent service, String resolvedType) {
13210        enforceNotIsolatedCaller("peekService");
13211        // Refuse possible leaked file descriptors
13212        if (service != null && service.hasFileDescriptors() == true) {
13213            throw new IllegalArgumentException("File descriptors passed in Intent");
13214        }
13215        synchronized(this) {
13216            return mServices.peekServiceLocked(service, resolvedType);
13217        }
13218    }
13219
13220    public boolean stopServiceToken(ComponentName className, IBinder token,
13221            int startId) {
13222        synchronized(this) {
13223            return mServices.stopServiceTokenLocked(className, token, startId);
13224        }
13225    }
13226
13227    public void setServiceForeground(ComponentName className, IBinder token,
13228            int id, Notification notification, boolean removeNotification) {
13229        synchronized(this) {
13230            mServices.setServiceForegroundLocked(className, token, id, notification,
13231                    removeNotification);
13232        }
13233    }
13234
13235    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13236            boolean requireFull, String name, String callerPackage) {
13237        final int callingUserId = UserHandle.getUserId(callingUid);
13238        if (callingUserId != userId) {
13239            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13240                if ((requireFull || checkComponentPermission(
13241                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13242                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13243                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13244                                callingPid, callingUid, -1, true)
13245                                != PackageManager.PERMISSION_GRANTED) {
13246                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13247                        // In this case, they would like to just execute as their
13248                        // owner user instead of failing.
13249                        userId = callingUserId;
13250                    } else {
13251                        StringBuilder builder = new StringBuilder(128);
13252                        builder.append("Permission Denial: ");
13253                        builder.append(name);
13254                        if (callerPackage != null) {
13255                            builder.append(" from ");
13256                            builder.append(callerPackage);
13257                        }
13258                        builder.append(" asks to run as user ");
13259                        builder.append(userId);
13260                        builder.append(" but is calling from user ");
13261                        builder.append(UserHandle.getUserId(callingUid));
13262                        builder.append("; this requires ");
13263                        builder.append(INTERACT_ACROSS_USERS_FULL);
13264                        if (!requireFull) {
13265                            builder.append(" or ");
13266                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13267                        }
13268                        String msg = builder.toString();
13269                        Slog.w(TAG, msg);
13270                        throw new SecurityException(msg);
13271                    }
13272                }
13273            }
13274            if (userId == UserHandle.USER_CURRENT
13275                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13276                // Note that we may be accessing this outside of a lock...
13277                // shouldn't be a big deal, if this is being called outside
13278                // of a locked context there is intrinsically a race with
13279                // the value the caller will receive and someone else changing it.
13280                userId = mCurrentUserId;
13281            }
13282            if (!allowAll && userId < 0) {
13283                throw new IllegalArgumentException(
13284                        "Call does not support special user #" + userId);
13285            }
13286        }
13287        return userId;
13288    }
13289
13290    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13291            String className, int flags) {
13292        boolean result = false;
13293        // For apps that don't have pre-defined UIDs, check for permission
13294        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13295            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13296                if (ActivityManager.checkUidPermission(
13297                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13298                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13299                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13300                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13301                            + " requests FLAG_SINGLE_USER, but app does not hold "
13302                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13303                    Slog.w(TAG, msg);
13304                    throw new SecurityException(msg);
13305                }
13306                // Permission passed
13307                result = true;
13308            }
13309        } else if ("system".equals(componentProcessName)) {
13310            result = true;
13311        } else {
13312            // App with pre-defined UID, check if it's a persistent app
13313            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13314        }
13315        if (DEBUG_MU) {
13316            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13317                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13318        }
13319        return result;
13320    }
13321
13322    /**
13323     * Checks to see if the caller is in the same app as the singleton
13324     * component, or the component is in a special app. It allows special apps
13325     * to export singleton components but prevents exporting singleton
13326     * components for regular apps.
13327     */
13328    boolean isValidSingletonCall(int callingUid, int componentUid) {
13329        int componentAppId = UserHandle.getAppId(componentUid);
13330        return UserHandle.isSameApp(callingUid, componentUid)
13331                || componentAppId == Process.SYSTEM_UID
13332                || componentAppId == Process.PHONE_UID
13333                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13334                        == PackageManager.PERMISSION_GRANTED;
13335    }
13336
13337    public int bindService(IApplicationThread caller, IBinder token,
13338            Intent service, String resolvedType,
13339            IServiceConnection connection, int flags, int userId) {
13340        enforceNotIsolatedCaller("bindService");
13341        // Refuse possible leaked file descriptors
13342        if (service != null && service.hasFileDescriptors() == true) {
13343            throw new IllegalArgumentException("File descriptors passed in Intent");
13344        }
13345
13346        synchronized(this) {
13347            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13348                    connection, flags, userId);
13349        }
13350    }
13351
13352    public boolean unbindService(IServiceConnection connection) {
13353        synchronized (this) {
13354            return mServices.unbindServiceLocked(connection);
13355        }
13356    }
13357
13358    public void publishService(IBinder token, Intent intent, IBinder service) {
13359        // Refuse possible leaked file descriptors
13360        if (intent != null && intent.hasFileDescriptors() == true) {
13361            throw new IllegalArgumentException("File descriptors passed in Intent");
13362        }
13363
13364        synchronized(this) {
13365            if (!(token instanceof ServiceRecord)) {
13366                throw new IllegalArgumentException("Invalid service token");
13367            }
13368            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13369        }
13370    }
13371
13372    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13373        // Refuse possible leaked file descriptors
13374        if (intent != null && intent.hasFileDescriptors() == true) {
13375            throw new IllegalArgumentException("File descriptors passed in Intent");
13376        }
13377
13378        synchronized(this) {
13379            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13380        }
13381    }
13382
13383    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13384        synchronized(this) {
13385            if (!(token instanceof ServiceRecord)) {
13386                throw new IllegalArgumentException("Invalid service token");
13387            }
13388            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13389        }
13390    }
13391
13392    // =========================================================
13393    // BACKUP AND RESTORE
13394    // =========================================================
13395
13396    // Cause the target app to be launched if necessary and its backup agent
13397    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13398    // activity manager to announce its creation.
13399    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13400        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13401        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13402
13403        synchronized(this) {
13404            // !!! TODO: currently no check here that we're already bound
13405            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13406            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13407            synchronized (stats) {
13408                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13409            }
13410
13411            // Backup agent is now in use, its package can't be stopped.
13412            try {
13413                AppGlobals.getPackageManager().setPackageStoppedState(
13414                        app.packageName, false, UserHandle.getUserId(app.uid));
13415            } catch (RemoteException e) {
13416            } catch (IllegalArgumentException e) {
13417                Slog.w(TAG, "Failed trying to unstop package "
13418                        + app.packageName + ": " + e);
13419            }
13420
13421            BackupRecord r = new BackupRecord(ss, app, backupMode);
13422            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13423                    ? new ComponentName(app.packageName, app.backupAgentName)
13424                    : new ComponentName("android", "FullBackupAgent");
13425            // startProcessLocked() returns existing proc's record if it's already running
13426            ProcessRecord proc = startProcessLocked(app.processName, app,
13427                    false, 0, "backup", hostingName, false, false, false);
13428            if (proc == null) {
13429                Slog.e(TAG, "Unable to start backup agent process " + r);
13430                return false;
13431            }
13432
13433            r.app = proc;
13434            mBackupTarget = r;
13435            mBackupAppName = app.packageName;
13436
13437            // Try not to kill the process during backup
13438            updateOomAdjLocked(proc);
13439
13440            // If the process is already attached, schedule the creation of the backup agent now.
13441            // If it is not yet live, this will be done when it attaches to the framework.
13442            if (proc.thread != null) {
13443                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13444                try {
13445                    proc.thread.scheduleCreateBackupAgent(app,
13446                            compatibilityInfoForPackageLocked(app), backupMode);
13447                } catch (RemoteException e) {
13448                    // Will time out on the backup manager side
13449                }
13450            } else {
13451                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13452            }
13453            // Invariants: at this point, the target app process exists and the application
13454            // is either already running or in the process of coming up.  mBackupTarget and
13455            // mBackupAppName describe the app, so that when it binds back to the AM we
13456            // know that it's scheduled for a backup-agent operation.
13457        }
13458
13459        return true;
13460    }
13461
13462    @Override
13463    public void clearPendingBackup() {
13464        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13465        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13466
13467        synchronized (this) {
13468            mBackupTarget = null;
13469            mBackupAppName = null;
13470        }
13471    }
13472
13473    // A backup agent has just come up
13474    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13475        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13476                + " = " + agent);
13477
13478        synchronized(this) {
13479            if (!agentPackageName.equals(mBackupAppName)) {
13480                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13481                return;
13482            }
13483        }
13484
13485        long oldIdent = Binder.clearCallingIdentity();
13486        try {
13487            IBackupManager bm = IBackupManager.Stub.asInterface(
13488                    ServiceManager.getService(Context.BACKUP_SERVICE));
13489            bm.agentConnected(agentPackageName, agent);
13490        } catch (RemoteException e) {
13491            // can't happen; the backup manager service is local
13492        } catch (Exception e) {
13493            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13494            e.printStackTrace();
13495        } finally {
13496            Binder.restoreCallingIdentity(oldIdent);
13497        }
13498    }
13499
13500    // done with this agent
13501    public void unbindBackupAgent(ApplicationInfo appInfo) {
13502        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13503        if (appInfo == null) {
13504            Slog.w(TAG, "unbind backup agent for null app");
13505            return;
13506        }
13507
13508        synchronized(this) {
13509            try {
13510                if (mBackupAppName == null) {
13511                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13512                    return;
13513                }
13514
13515                if (!mBackupAppName.equals(appInfo.packageName)) {
13516                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13517                    return;
13518                }
13519
13520                // Not backing this app up any more; reset its OOM adjustment
13521                final ProcessRecord proc = mBackupTarget.app;
13522                updateOomAdjLocked(proc);
13523
13524                // If the app crashed during backup, 'thread' will be null here
13525                if (proc.thread != null) {
13526                    try {
13527                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13528                                compatibilityInfoForPackageLocked(appInfo));
13529                    } catch (Exception e) {
13530                        Slog.e(TAG, "Exception when unbinding backup agent:");
13531                        e.printStackTrace();
13532                    }
13533                }
13534            } finally {
13535                mBackupTarget = null;
13536                mBackupAppName = null;
13537            }
13538        }
13539    }
13540    // =========================================================
13541    // BROADCASTS
13542    // =========================================================
13543
13544    private final List getStickiesLocked(String action, IntentFilter filter,
13545            List cur, int userId) {
13546        final ContentResolver resolver = mContext.getContentResolver();
13547        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13548        if (stickies == null) {
13549            return cur;
13550        }
13551        final ArrayList<Intent> list = stickies.get(action);
13552        if (list == null) {
13553            return cur;
13554        }
13555        int N = list.size();
13556        for (int i=0; i<N; i++) {
13557            Intent intent = list.get(i);
13558            if (filter.match(resolver, intent, true, TAG) >= 0) {
13559                if (cur == null) {
13560                    cur = new ArrayList<Intent>();
13561                }
13562                cur.add(intent);
13563            }
13564        }
13565        return cur;
13566    }
13567
13568    boolean isPendingBroadcastProcessLocked(int pid) {
13569        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13570                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13571    }
13572
13573    void skipPendingBroadcastLocked(int pid) {
13574            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13575            for (BroadcastQueue queue : mBroadcastQueues) {
13576                queue.skipPendingBroadcastLocked(pid);
13577            }
13578    }
13579
13580    // The app just attached; send any pending broadcasts that it should receive
13581    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13582        boolean didSomething = false;
13583        for (BroadcastQueue queue : mBroadcastQueues) {
13584            didSomething |= queue.sendPendingBroadcastsLocked(app);
13585        }
13586        return didSomething;
13587    }
13588
13589    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13590            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13591        enforceNotIsolatedCaller("registerReceiver");
13592        int callingUid;
13593        int callingPid;
13594        synchronized(this) {
13595            ProcessRecord callerApp = null;
13596            if (caller != null) {
13597                callerApp = getRecordForAppLocked(caller);
13598                if (callerApp == null) {
13599                    throw new SecurityException(
13600                            "Unable to find app for caller " + caller
13601                            + " (pid=" + Binder.getCallingPid()
13602                            + ") when registering receiver " + receiver);
13603                }
13604                if (callerApp.info.uid != Process.SYSTEM_UID &&
13605                        !callerApp.pkgList.containsKey(callerPackage) &&
13606                        !"android".equals(callerPackage)) {
13607                    throw new SecurityException("Given caller package " + callerPackage
13608                            + " is not running in process " + callerApp);
13609                }
13610                callingUid = callerApp.info.uid;
13611                callingPid = callerApp.pid;
13612            } else {
13613                callerPackage = null;
13614                callingUid = Binder.getCallingUid();
13615                callingPid = Binder.getCallingPid();
13616            }
13617
13618            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13619                    true, true, "registerReceiver", callerPackage);
13620
13621            List allSticky = null;
13622
13623            // Look for any matching sticky broadcasts...
13624            Iterator actions = filter.actionsIterator();
13625            if (actions != null) {
13626                while (actions.hasNext()) {
13627                    String action = (String)actions.next();
13628                    allSticky = getStickiesLocked(action, filter, allSticky,
13629                            UserHandle.USER_ALL);
13630                    allSticky = getStickiesLocked(action, filter, allSticky,
13631                            UserHandle.getUserId(callingUid));
13632                }
13633            } else {
13634                allSticky = getStickiesLocked(null, filter, allSticky,
13635                        UserHandle.USER_ALL);
13636                allSticky = getStickiesLocked(null, filter, allSticky,
13637                        UserHandle.getUserId(callingUid));
13638            }
13639
13640            // The first sticky in the list is returned directly back to
13641            // the client.
13642            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13643
13644            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13645                    + ": " + sticky);
13646
13647            if (receiver == null) {
13648                return sticky;
13649            }
13650
13651            ReceiverList rl
13652                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13653            if (rl == null) {
13654                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13655                        userId, receiver);
13656                if (rl.app != null) {
13657                    rl.app.receivers.add(rl);
13658                } else {
13659                    try {
13660                        receiver.asBinder().linkToDeath(rl, 0);
13661                    } catch (RemoteException e) {
13662                        return sticky;
13663                    }
13664                    rl.linkedToDeath = true;
13665                }
13666                mRegisteredReceivers.put(receiver.asBinder(), rl);
13667            } else if (rl.uid != callingUid) {
13668                throw new IllegalArgumentException(
13669                        "Receiver requested to register for uid " + callingUid
13670                        + " was previously registered for uid " + rl.uid);
13671            } else if (rl.pid != callingPid) {
13672                throw new IllegalArgumentException(
13673                        "Receiver requested to register for pid " + callingPid
13674                        + " was previously registered for pid " + rl.pid);
13675            } else if (rl.userId != userId) {
13676                throw new IllegalArgumentException(
13677                        "Receiver requested to register for user " + userId
13678                        + " was previously registered for user " + rl.userId);
13679            }
13680            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13681                    permission, callingUid, userId);
13682            rl.add(bf);
13683            if (!bf.debugCheck()) {
13684                Slog.w(TAG, "==> For Dynamic broadast");
13685            }
13686            mReceiverResolver.addFilter(bf);
13687
13688            // Enqueue broadcasts for all existing stickies that match
13689            // this filter.
13690            if (allSticky != null) {
13691                ArrayList receivers = new ArrayList();
13692                receivers.add(bf);
13693
13694                int N = allSticky.size();
13695                for (int i=0; i<N; i++) {
13696                    Intent intent = (Intent)allSticky.get(i);
13697                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13698                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13699                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13700                            null, null, false, true, true, -1);
13701                    queue.enqueueParallelBroadcastLocked(r);
13702                    queue.scheduleBroadcastsLocked();
13703                }
13704            }
13705
13706            return sticky;
13707        }
13708    }
13709
13710    public void unregisterReceiver(IIntentReceiver receiver) {
13711        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13712
13713        final long origId = Binder.clearCallingIdentity();
13714        try {
13715            boolean doTrim = false;
13716
13717            synchronized(this) {
13718                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13719                if (rl != null) {
13720                    if (rl.curBroadcast != null) {
13721                        BroadcastRecord r = rl.curBroadcast;
13722                        final boolean doNext = finishReceiverLocked(
13723                                receiver.asBinder(), r.resultCode, r.resultData,
13724                                r.resultExtras, r.resultAbort);
13725                        if (doNext) {
13726                            doTrim = true;
13727                            r.queue.processNextBroadcast(false);
13728                        }
13729                    }
13730
13731                    if (rl.app != null) {
13732                        rl.app.receivers.remove(rl);
13733                    }
13734                    removeReceiverLocked(rl);
13735                    if (rl.linkedToDeath) {
13736                        rl.linkedToDeath = false;
13737                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13738                    }
13739                }
13740            }
13741
13742            // If we actually concluded any broadcasts, we might now be able
13743            // to trim the recipients' apps from our working set
13744            if (doTrim) {
13745                trimApplications();
13746                return;
13747            }
13748
13749        } finally {
13750            Binder.restoreCallingIdentity(origId);
13751        }
13752    }
13753
13754    void removeReceiverLocked(ReceiverList rl) {
13755        mRegisteredReceivers.remove(rl.receiver.asBinder());
13756        int N = rl.size();
13757        for (int i=0; i<N; i++) {
13758            mReceiverResolver.removeFilter(rl.get(i));
13759        }
13760    }
13761
13762    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13763        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13764            ProcessRecord r = mLruProcesses.get(i);
13765            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13766                try {
13767                    r.thread.dispatchPackageBroadcast(cmd, packages);
13768                } catch (RemoteException ex) {
13769                }
13770            }
13771        }
13772    }
13773
13774    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13775            int[] users) {
13776        List<ResolveInfo> receivers = null;
13777        try {
13778            HashSet<ComponentName> singleUserReceivers = null;
13779            boolean scannedFirstReceivers = false;
13780            for (int user : users) {
13781                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13782                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13783                if (user != 0 && newReceivers != null) {
13784                    // If this is not the primary user, we need to check for
13785                    // any receivers that should be filtered out.
13786                    for (int i=0; i<newReceivers.size(); i++) {
13787                        ResolveInfo ri = newReceivers.get(i);
13788                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13789                            newReceivers.remove(i);
13790                            i--;
13791                        }
13792                    }
13793                }
13794                if (newReceivers != null && newReceivers.size() == 0) {
13795                    newReceivers = null;
13796                }
13797                if (receivers == null) {
13798                    receivers = newReceivers;
13799                } else if (newReceivers != null) {
13800                    // We need to concatenate the additional receivers
13801                    // found with what we have do far.  This would be easy,
13802                    // but we also need to de-dup any receivers that are
13803                    // singleUser.
13804                    if (!scannedFirstReceivers) {
13805                        // Collect any single user receivers we had already retrieved.
13806                        scannedFirstReceivers = true;
13807                        for (int i=0; i<receivers.size(); i++) {
13808                            ResolveInfo ri = receivers.get(i);
13809                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13810                                ComponentName cn = new ComponentName(
13811                                        ri.activityInfo.packageName, ri.activityInfo.name);
13812                                if (singleUserReceivers == null) {
13813                                    singleUserReceivers = new HashSet<ComponentName>();
13814                                }
13815                                singleUserReceivers.add(cn);
13816                            }
13817                        }
13818                    }
13819                    // Add the new results to the existing results, tracking
13820                    // and de-dupping single user receivers.
13821                    for (int i=0; i<newReceivers.size(); i++) {
13822                        ResolveInfo ri = newReceivers.get(i);
13823                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13824                            ComponentName cn = new ComponentName(
13825                                    ri.activityInfo.packageName, ri.activityInfo.name);
13826                            if (singleUserReceivers == null) {
13827                                singleUserReceivers = new HashSet<ComponentName>();
13828                            }
13829                            if (!singleUserReceivers.contains(cn)) {
13830                                singleUserReceivers.add(cn);
13831                                receivers.add(ri);
13832                            }
13833                        } else {
13834                            receivers.add(ri);
13835                        }
13836                    }
13837                }
13838            }
13839        } catch (RemoteException ex) {
13840            // pm is in same process, this will never happen.
13841        }
13842        return receivers;
13843    }
13844
13845    private final int broadcastIntentLocked(ProcessRecord callerApp,
13846            String callerPackage, Intent intent, String resolvedType,
13847            IIntentReceiver resultTo, int resultCode, String resultData,
13848            Bundle map, String requiredPermission, int appOp,
13849            boolean ordered, boolean sticky, int callingPid, int callingUid,
13850            int userId) {
13851        intent = new Intent(intent);
13852
13853        // By default broadcasts do not go to stopped apps.
13854        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13855
13856        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13857            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13858            + " ordered=" + ordered + " userid=" + userId);
13859        if ((resultTo != null) && !ordered) {
13860            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13861        }
13862
13863        userId = handleIncomingUser(callingPid, callingUid, userId,
13864                true, false, "broadcast", callerPackage);
13865
13866        // Make sure that the user who is receiving this broadcast is started.
13867        // If not, we will just skip it.
13868        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13869            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13870                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13871                Slog.w(TAG, "Skipping broadcast of " + intent
13872                        + ": user " + userId + " is stopped");
13873                return ActivityManager.BROADCAST_SUCCESS;
13874            }
13875        }
13876
13877        /*
13878         * Prevent non-system code (defined here to be non-persistent
13879         * processes) from sending protected broadcasts.
13880         */
13881        int callingAppId = UserHandle.getAppId(callingUid);
13882        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13883                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13884                || callingUid == 0) {
13885            // Always okay.
13886        } else if (callerApp == null || !callerApp.persistent) {
13887            try {
13888                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13889                        intent.getAction())) {
13890                    String msg = "Permission Denial: not allowed to send broadcast "
13891                            + intent.getAction() + " from pid="
13892                            + callingPid + ", uid=" + callingUid;
13893                    Slog.w(TAG, msg);
13894                    throw new SecurityException(msg);
13895                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13896                    // Special case for compatibility: we don't want apps to send this,
13897                    // but historically it has not been protected and apps may be using it
13898                    // to poke their own app widget.  So, instead of making it protected,
13899                    // just limit it to the caller.
13900                    if (callerApp == null) {
13901                        String msg = "Permission Denial: not allowed to send broadcast "
13902                                + intent.getAction() + " from unknown caller.";
13903                        Slog.w(TAG, msg);
13904                        throw new SecurityException(msg);
13905                    } else if (intent.getComponent() != null) {
13906                        // They are good enough to send to an explicit component...  verify
13907                        // it is being sent to the calling app.
13908                        if (!intent.getComponent().getPackageName().equals(
13909                                callerApp.info.packageName)) {
13910                            String msg = "Permission Denial: not allowed to send broadcast "
13911                                    + intent.getAction() + " to "
13912                                    + intent.getComponent().getPackageName() + " from "
13913                                    + callerApp.info.packageName;
13914                            Slog.w(TAG, msg);
13915                            throw new SecurityException(msg);
13916                        }
13917                    } else {
13918                        // Limit broadcast to their own package.
13919                        intent.setPackage(callerApp.info.packageName);
13920                    }
13921                }
13922            } catch (RemoteException e) {
13923                Slog.w(TAG, "Remote exception", e);
13924                return ActivityManager.BROADCAST_SUCCESS;
13925            }
13926        }
13927
13928        // Handle special intents: if this broadcast is from the package
13929        // manager about a package being removed, we need to remove all of
13930        // its activities from the history stack.
13931        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13932                intent.getAction());
13933        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13934                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13935                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13936                || uidRemoved) {
13937            if (checkComponentPermission(
13938                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13939                    callingPid, callingUid, -1, true)
13940                    == PackageManager.PERMISSION_GRANTED) {
13941                if (uidRemoved) {
13942                    final Bundle intentExtras = intent.getExtras();
13943                    final int uid = intentExtras != null
13944                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13945                    if (uid >= 0) {
13946                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13947                        synchronized (bs) {
13948                            bs.removeUidStatsLocked(uid);
13949                        }
13950                        mAppOpsService.uidRemoved(uid);
13951                    }
13952                } else {
13953                    // If resources are unavailable just force stop all
13954                    // those packages and flush the attribute cache as well.
13955                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13956                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13957                        if (list != null && (list.length > 0)) {
13958                            for (String pkg : list) {
13959                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13960                                        "storage unmount");
13961                            }
13962                            sendPackageBroadcastLocked(
13963                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13964                        }
13965                    } else {
13966                        Uri data = intent.getData();
13967                        String ssp;
13968                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13969                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13970                                    intent.getAction());
13971                            boolean fullUninstall = removed &&
13972                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13973                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13974                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13975                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13976                                        false, fullUninstall, userId,
13977                                        removed ? "pkg removed" : "pkg changed");
13978                            }
13979                            if (removed) {
13980                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13981                                        new String[] {ssp}, userId);
13982                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13983                                    mAppOpsService.packageRemoved(
13984                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13985
13986                                    // Remove all permissions granted from/to this package
13987                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13988                                }
13989                            }
13990                        }
13991                    }
13992                }
13993            } else {
13994                String msg = "Permission Denial: " + intent.getAction()
13995                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13996                        + ", uid=" + callingUid + ")"
13997                        + " requires "
13998                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13999                Slog.w(TAG, msg);
14000                throw new SecurityException(msg);
14001            }
14002
14003        // Special case for adding a package: by default turn on compatibility
14004        // mode.
14005        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14006            Uri data = intent.getData();
14007            String ssp;
14008            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14009                mCompatModePackages.handlePackageAddedLocked(ssp,
14010                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14011            }
14012        }
14013
14014        /*
14015         * If this is the time zone changed action, queue up a message that will reset the timezone
14016         * of all currently running processes. This message will get queued up before the broadcast
14017         * happens.
14018         */
14019        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14020            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14021        }
14022
14023        /*
14024         * If the user set the time, let all running processes know.
14025         */
14026        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14027            final int is24Hour = intent.getBooleanExtra(
14028                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14029            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14030        }
14031
14032        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14033            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14034        }
14035
14036        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14037            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14038            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14039        }
14040
14041        // Add to the sticky list if requested.
14042        if (sticky) {
14043            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14044                    callingPid, callingUid)
14045                    != PackageManager.PERMISSION_GRANTED) {
14046                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14047                        + callingPid + ", uid=" + callingUid
14048                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14049                Slog.w(TAG, msg);
14050                throw new SecurityException(msg);
14051            }
14052            if (requiredPermission != null) {
14053                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14054                        + " and enforce permission " + requiredPermission);
14055                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14056            }
14057            if (intent.getComponent() != null) {
14058                throw new SecurityException(
14059                        "Sticky broadcasts can't target a specific component");
14060            }
14061            // We use userId directly here, since the "all" target is maintained
14062            // as a separate set of sticky broadcasts.
14063            if (userId != UserHandle.USER_ALL) {
14064                // But first, if this is not a broadcast to all users, then
14065                // make sure it doesn't conflict with an existing broadcast to
14066                // all users.
14067                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14068                        UserHandle.USER_ALL);
14069                if (stickies != null) {
14070                    ArrayList<Intent> list = stickies.get(intent.getAction());
14071                    if (list != null) {
14072                        int N = list.size();
14073                        int i;
14074                        for (i=0; i<N; i++) {
14075                            if (intent.filterEquals(list.get(i))) {
14076                                throw new IllegalArgumentException(
14077                                        "Sticky broadcast " + intent + " for user "
14078                                        + userId + " conflicts with existing global broadcast");
14079                            }
14080                        }
14081                    }
14082                }
14083            }
14084            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14085            if (stickies == null) {
14086                stickies = new ArrayMap<String, ArrayList<Intent>>();
14087                mStickyBroadcasts.put(userId, stickies);
14088            }
14089            ArrayList<Intent> list = stickies.get(intent.getAction());
14090            if (list == null) {
14091                list = new ArrayList<Intent>();
14092                stickies.put(intent.getAction(), list);
14093            }
14094            int N = list.size();
14095            int i;
14096            for (i=0; i<N; i++) {
14097                if (intent.filterEquals(list.get(i))) {
14098                    // This sticky already exists, replace it.
14099                    list.set(i, new Intent(intent));
14100                    break;
14101                }
14102            }
14103            if (i >= N) {
14104                list.add(new Intent(intent));
14105            }
14106        }
14107
14108        int[] users;
14109        if (userId == UserHandle.USER_ALL) {
14110            // Caller wants broadcast to go to all started users.
14111            users = mStartedUserArray;
14112        } else {
14113            // Caller wants broadcast to go to one specific user.
14114            users = new int[] {userId};
14115        }
14116
14117        // Figure out who all will receive this broadcast.
14118        List receivers = null;
14119        List<BroadcastFilter> registeredReceivers = null;
14120        // Need to resolve the intent to interested receivers...
14121        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14122                 == 0) {
14123            receivers = collectReceiverComponents(intent, resolvedType, users);
14124        }
14125        if (intent.getComponent() == null) {
14126            registeredReceivers = mReceiverResolver.queryIntent(intent,
14127                    resolvedType, false, userId);
14128        }
14129
14130        final boolean replacePending =
14131                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14132
14133        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14134                + " replacePending=" + replacePending);
14135
14136        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14137        if (!ordered && NR > 0) {
14138            // If we are not serializing this broadcast, then send the
14139            // registered receivers separately so they don't wait for the
14140            // components to be launched.
14141            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14142            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14143                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14144                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14145                    ordered, sticky, false, userId);
14146            if (DEBUG_BROADCAST) Slog.v(
14147                    TAG, "Enqueueing parallel broadcast " + r);
14148            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14149            if (!replaced) {
14150                queue.enqueueParallelBroadcastLocked(r);
14151                queue.scheduleBroadcastsLocked();
14152            }
14153            registeredReceivers = null;
14154            NR = 0;
14155        }
14156
14157        // Merge into one list.
14158        int ir = 0;
14159        if (receivers != null) {
14160            // A special case for PACKAGE_ADDED: do not allow the package
14161            // being added to see this broadcast.  This prevents them from
14162            // using this as a back door to get run as soon as they are
14163            // installed.  Maybe in the future we want to have a special install
14164            // broadcast or such for apps, but we'd like to deliberately make
14165            // this decision.
14166            String skipPackages[] = null;
14167            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14168                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14169                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14170                Uri data = intent.getData();
14171                if (data != null) {
14172                    String pkgName = data.getSchemeSpecificPart();
14173                    if (pkgName != null) {
14174                        skipPackages = new String[] { pkgName };
14175                    }
14176                }
14177            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14178                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14179            }
14180            if (skipPackages != null && (skipPackages.length > 0)) {
14181                for (String skipPackage : skipPackages) {
14182                    if (skipPackage != null) {
14183                        int NT = receivers.size();
14184                        for (int it=0; it<NT; it++) {
14185                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14186                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14187                                receivers.remove(it);
14188                                it--;
14189                                NT--;
14190                            }
14191                        }
14192                    }
14193                }
14194            }
14195
14196            int NT = receivers != null ? receivers.size() : 0;
14197            int it = 0;
14198            ResolveInfo curt = null;
14199            BroadcastFilter curr = null;
14200            while (it < NT && ir < NR) {
14201                if (curt == null) {
14202                    curt = (ResolveInfo)receivers.get(it);
14203                }
14204                if (curr == null) {
14205                    curr = registeredReceivers.get(ir);
14206                }
14207                if (curr.getPriority() >= curt.priority) {
14208                    // Insert this broadcast record into the final list.
14209                    receivers.add(it, curr);
14210                    ir++;
14211                    curr = null;
14212                    it++;
14213                    NT++;
14214                } else {
14215                    // Skip to the next ResolveInfo in the final list.
14216                    it++;
14217                    curt = null;
14218                }
14219            }
14220        }
14221        while (ir < NR) {
14222            if (receivers == null) {
14223                receivers = new ArrayList();
14224            }
14225            receivers.add(registeredReceivers.get(ir));
14226            ir++;
14227        }
14228
14229        if ((receivers != null && receivers.size() > 0)
14230                || resultTo != null) {
14231            BroadcastQueue queue = broadcastQueueForIntent(intent);
14232            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14233                    callerPackage, callingPid, callingUid, resolvedType,
14234                    requiredPermission, appOp, receivers, resultTo, resultCode,
14235                    resultData, map, ordered, sticky, false, userId);
14236            if (DEBUG_BROADCAST) Slog.v(
14237                    TAG, "Enqueueing ordered broadcast " + r
14238                    + ": prev had " + queue.mOrderedBroadcasts.size());
14239            if (DEBUG_BROADCAST) {
14240                int seq = r.intent.getIntExtra("seq", -1);
14241                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14242            }
14243            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14244            if (!replaced) {
14245                queue.enqueueOrderedBroadcastLocked(r);
14246                queue.scheduleBroadcastsLocked();
14247            }
14248        }
14249
14250        return ActivityManager.BROADCAST_SUCCESS;
14251    }
14252
14253    final Intent verifyBroadcastLocked(Intent intent) {
14254        // Refuse possible leaked file descriptors
14255        if (intent != null && intent.hasFileDescriptors() == true) {
14256            throw new IllegalArgumentException("File descriptors passed in Intent");
14257        }
14258
14259        int flags = intent.getFlags();
14260
14261        if (!mProcessesReady) {
14262            // if the caller really truly claims to know what they're doing, go
14263            // ahead and allow the broadcast without launching any receivers
14264            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14265                intent = new Intent(intent);
14266                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14267            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14268                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14269                        + " before boot completion");
14270                throw new IllegalStateException("Cannot broadcast before boot completed");
14271            }
14272        }
14273
14274        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14275            throw new IllegalArgumentException(
14276                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14277        }
14278
14279        return intent;
14280    }
14281
14282    public final int broadcastIntent(IApplicationThread caller,
14283            Intent intent, String resolvedType, IIntentReceiver resultTo,
14284            int resultCode, String resultData, Bundle map,
14285            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14286        enforceNotIsolatedCaller("broadcastIntent");
14287        synchronized(this) {
14288            intent = verifyBroadcastLocked(intent);
14289
14290            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14291            final int callingPid = Binder.getCallingPid();
14292            final int callingUid = Binder.getCallingUid();
14293            final long origId = Binder.clearCallingIdentity();
14294            int res = broadcastIntentLocked(callerApp,
14295                    callerApp != null ? callerApp.info.packageName : null,
14296                    intent, resolvedType, resultTo,
14297                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14298                    callingPid, callingUid, userId);
14299            Binder.restoreCallingIdentity(origId);
14300            return res;
14301        }
14302    }
14303
14304    int broadcastIntentInPackage(String packageName, int uid,
14305            Intent intent, String resolvedType, IIntentReceiver resultTo,
14306            int resultCode, String resultData, Bundle map,
14307            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14308        synchronized(this) {
14309            intent = verifyBroadcastLocked(intent);
14310
14311            final long origId = Binder.clearCallingIdentity();
14312            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14313                    resultTo, resultCode, resultData, map, requiredPermission,
14314                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14315            Binder.restoreCallingIdentity(origId);
14316            return res;
14317        }
14318    }
14319
14320    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14321        // Refuse possible leaked file descriptors
14322        if (intent != null && intent.hasFileDescriptors() == true) {
14323            throw new IllegalArgumentException("File descriptors passed in Intent");
14324        }
14325
14326        userId = handleIncomingUser(Binder.getCallingPid(),
14327                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14328
14329        synchronized(this) {
14330            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14331                    != PackageManager.PERMISSION_GRANTED) {
14332                String msg = "Permission Denial: unbroadcastIntent() from pid="
14333                        + Binder.getCallingPid()
14334                        + ", uid=" + Binder.getCallingUid()
14335                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14336                Slog.w(TAG, msg);
14337                throw new SecurityException(msg);
14338            }
14339            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14340            if (stickies != null) {
14341                ArrayList<Intent> list = stickies.get(intent.getAction());
14342                if (list != null) {
14343                    int N = list.size();
14344                    int i;
14345                    for (i=0; i<N; i++) {
14346                        if (intent.filterEquals(list.get(i))) {
14347                            list.remove(i);
14348                            break;
14349                        }
14350                    }
14351                    if (list.size() <= 0) {
14352                        stickies.remove(intent.getAction());
14353                    }
14354                }
14355                if (stickies.size() <= 0) {
14356                    mStickyBroadcasts.remove(userId);
14357                }
14358            }
14359        }
14360    }
14361
14362    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14363            String resultData, Bundle resultExtras, boolean resultAbort) {
14364        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14365        if (r == null) {
14366            Slog.w(TAG, "finishReceiver called but not found on queue");
14367            return false;
14368        }
14369
14370        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14371    }
14372
14373    void backgroundServicesFinishedLocked(int userId) {
14374        for (BroadcastQueue queue : mBroadcastQueues) {
14375            queue.backgroundServicesFinishedLocked(userId);
14376        }
14377    }
14378
14379    public void finishReceiver(IBinder who, int resultCode, String resultData,
14380            Bundle resultExtras, boolean resultAbort) {
14381        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14382
14383        // Refuse possible leaked file descriptors
14384        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14385            throw new IllegalArgumentException("File descriptors passed in Bundle");
14386        }
14387
14388        final long origId = Binder.clearCallingIdentity();
14389        try {
14390            boolean doNext = false;
14391            BroadcastRecord r;
14392
14393            synchronized(this) {
14394                r = broadcastRecordForReceiverLocked(who);
14395                if (r != null) {
14396                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14397                        resultData, resultExtras, resultAbort, true);
14398                }
14399            }
14400
14401            if (doNext) {
14402                r.queue.processNextBroadcast(false);
14403            }
14404            trimApplications();
14405        } finally {
14406            Binder.restoreCallingIdentity(origId);
14407        }
14408    }
14409
14410    // =========================================================
14411    // INSTRUMENTATION
14412    // =========================================================
14413
14414    public boolean startInstrumentation(ComponentName className,
14415            String profileFile, int flags, Bundle arguments,
14416            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14417            int userId, String abiOverride) {
14418        enforceNotIsolatedCaller("startInstrumentation");
14419        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14420                userId, false, true, "startInstrumentation", null);
14421        // Refuse possible leaked file descriptors
14422        if (arguments != null && arguments.hasFileDescriptors()) {
14423            throw new IllegalArgumentException("File descriptors passed in Bundle");
14424        }
14425
14426        synchronized(this) {
14427            InstrumentationInfo ii = null;
14428            ApplicationInfo ai = null;
14429            try {
14430                ii = mContext.getPackageManager().getInstrumentationInfo(
14431                    className, STOCK_PM_FLAGS);
14432                ai = AppGlobals.getPackageManager().getApplicationInfo(
14433                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14434            } catch (PackageManager.NameNotFoundException e) {
14435            } catch (RemoteException e) {
14436            }
14437            if (ii == null) {
14438                reportStartInstrumentationFailure(watcher, className,
14439                        "Unable to find instrumentation info for: " + className);
14440                return false;
14441            }
14442            if (ai == null) {
14443                reportStartInstrumentationFailure(watcher, className,
14444                        "Unable to find instrumentation target package: " + ii.targetPackage);
14445                return false;
14446            }
14447
14448            int match = mContext.getPackageManager().checkSignatures(
14449                    ii.targetPackage, ii.packageName);
14450            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14451                String msg = "Permission Denial: starting instrumentation "
14452                        + className + " from pid="
14453                        + Binder.getCallingPid()
14454                        + ", uid=" + Binder.getCallingPid()
14455                        + " not allowed because package " + ii.packageName
14456                        + " does not have a signature matching the target "
14457                        + ii.targetPackage;
14458                reportStartInstrumentationFailure(watcher, className, msg);
14459                throw new SecurityException(msg);
14460            }
14461
14462            final long origId = Binder.clearCallingIdentity();
14463            // Instrumentation can kill and relaunch even persistent processes
14464            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14465                    "start instr");
14466            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14467            app.instrumentationClass = className;
14468            app.instrumentationInfo = ai;
14469            app.instrumentationProfileFile = profileFile;
14470            app.instrumentationArguments = arguments;
14471            app.instrumentationWatcher = watcher;
14472            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14473            app.instrumentationResultClass = className;
14474            Binder.restoreCallingIdentity(origId);
14475        }
14476
14477        return true;
14478    }
14479
14480    /**
14481     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14482     * error to the logs, but if somebody is watching, send the report there too.  This enables
14483     * the "am" command to report errors with more information.
14484     *
14485     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14486     * @param cn The component name of the instrumentation.
14487     * @param report The error report.
14488     */
14489    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14490            ComponentName cn, String report) {
14491        Slog.w(TAG, report);
14492        try {
14493            if (watcher != null) {
14494                Bundle results = new Bundle();
14495                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14496                results.putString("Error", report);
14497                watcher.instrumentationStatus(cn, -1, results);
14498            }
14499        } catch (RemoteException e) {
14500            Slog.w(TAG, e);
14501        }
14502    }
14503
14504    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14505        if (app.instrumentationWatcher != null) {
14506            try {
14507                // NOTE:  IInstrumentationWatcher *must* be oneway here
14508                app.instrumentationWatcher.instrumentationFinished(
14509                    app.instrumentationClass,
14510                    resultCode,
14511                    results);
14512            } catch (RemoteException e) {
14513            }
14514        }
14515        if (app.instrumentationUiAutomationConnection != null) {
14516            try {
14517                app.instrumentationUiAutomationConnection.shutdown();
14518            } catch (RemoteException re) {
14519                /* ignore */
14520            }
14521            // Only a UiAutomation can set this flag and now that
14522            // it is finished we make sure it is reset to its default.
14523            mUserIsMonkey = false;
14524        }
14525        app.instrumentationWatcher = null;
14526        app.instrumentationUiAutomationConnection = null;
14527        app.instrumentationClass = null;
14528        app.instrumentationInfo = null;
14529        app.instrumentationProfileFile = null;
14530        app.instrumentationArguments = null;
14531
14532        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14533                "finished inst");
14534    }
14535
14536    public void finishInstrumentation(IApplicationThread target,
14537            int resultCode, Bundle results) {
14538        int userId = UserHandle.getCallingUserId();
14539        // Refuse possible leaked file descriptors
14540        if (results != null && results.hasFileDescriptors()) {
14541            throw new IllegalArgumentException("File descriptors passed in Intent");
14542        }
14543
14544        synchronized(this) {
14545            ProcessRecord app = getRecordForAppLocked(target);
14546            if (app == null) {
14547                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14548                return;
14549            }
14550            final long origId = Binder.clearCallingIdentity();
14551            finishInstrumentationLocked(app, resultCode, results);
14552            Binder.restoreCallingIdentity(origId);
14553        }
14554    }
14555
14556    // =========================================================
14557    // CONFIGURATION
14558    // =========================================================
14559
14560    public ConfigurationInfo getDeviceConfigurationInfo() {
14561        ConfigurationInfo config = new ConfigurationInfo();
14562        synchronized (this) {
14563            config.reqTouchScreen = mConfiguration.touchscreen;
14564            config.reqKeyboardType = mConfiguration.keyboard;
14565            config.reqNavigation = mConfiguration.navigation;
14566            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14567                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14568                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14569            }
14570            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14571                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14572                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14573            }
14574            config.reqGlEsVersion = GL_ES_VERSION;
14575        }
14576        return config;
14577    }
14578
14579    ActivityStack getFocusedStack() {
14580        return mStackSupervisor.getFocusedStack();
14581    }
14582
14583    public Configuration getConfiguration() {
14584        Configuration ci;
14585        synchronized(this) {
14586            ci = new Configuration(mConfiguration);
14587        }
14588        return ci;
14589    }
14590
14591    public void updatePersistentConfiguration(Configuration values) {
14592        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14593                "updateConfiguration()");
14594        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14595                "updateConfiguration()");
14596        if (values == null) {
14597            throw new NullPointerException("Configuration must not be null");
14598        }
14599
14600        synchronized(this) {
14601            final long origId = Binder.clearCallingIdentity();
14602            updateConfigurationLocked(values, null, true, false);
14603            Binder.restoreCallingIdentity(origId);
14604        }
14605    }
14606
14607    public void updateConfiguration(Configuration values) {
14608        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14609                "updateConfiguration()");
14610
14611        synchronized(this) {
14612            if (values == null && mWindowManager != null) {
14613                // sentinel: fetch the current configuration from the window manager
14614                values = mWindowManager.computeNewConfiguration();
14615            }
14616
14617            if (mWindowManager != null) {
14618                mProcessList.applyDisplaySize(mWindowManager);
14619            }
14620
14621            final long origId = Binder.clearCallingIdentity();
14622            if (values != null) {
14623                Settings.System.clearConfiguration(values);
14624            }
14625            updateConfigurationLocked(values, null, false, false);
14626            Binder.restoreCallingIdentity(origId);
14627        }
14628    }
14629
14630    /**
14631     * Do either or both things: (1) change the current configuration, and (2)
14632     * make sure the given activity is running with the (now) current
14633     * configuration.  Returns true if the activity has been left running, or
14634     * false if <var>starting</var> is being destroyed to match the new
14635     * configuration.
14636     * @param persistent TODO
14637     */
14638    boolean updateConfigurationLocked(Configuration values,
14639            ActivityRecord starting, boolean persistent, boolean initLocale) {
14640        int changes = 0;
14641
14642        if (values != null) {
14643            Configuration newConfig = new Configuration(mConfiguration);
14644            changes = newConfig.updateFrom(values);
14645            if (changes != 0) {
14646                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14647                    Slog.i(TAG, "Updating configuration to: " + values);
14648                }
14649
14650                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14651
14652                if (values.locale != null && !initLocale) {
14653                    saveLocaleLocked(values.locale,
14654                                     !values.locale.equals(mConfiguration.locale),
14655                                     values.userSetLocale);
14656                }
14657
14658                mConfigurationSeq++;
14659                if (mConfigurationSeq <= 0) {
14660                    mConfigurationSeq = 1;
14661                }
14662                newConfig.seq = mConfigurationSeq;
14663                mConfiguration = newConfig;
14664                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14665                mUsageStatsService.noteStartConfig(newConfig);
14666
14667                final Configuration configCopy = new Configuration(mConfiguration);
14668
14669                // TODO: If our config changes, should we auto dismiss any currently
14670                // showing dialogs?
14671                mShowDialogs = shouldShowDialogs(newConfig);
14672
14673                AttributeCache ac = AttributeCache.instance();
14674                if (ac != null) {
14675                    ac.updateConfiguration(configCopy);
14676                }
14677
14678                // Make sure all resources in our process are updated
14679                // right now, so that anyone who is going to retrieve
14680                // resource values after we return will be sure to get
14681                // the new ones.  This is especially important during
14682                // boot, where the first config change needs to guarantee
14683                // all resources have that config before following boot
14684                // code is executed.
14685                mSystemThread.applyConfigurationToResources(configCopy);
14686
14687                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14688                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14689                    msg.obj = new Configuration(configCopy);
14690                    mHandler.sendMessage(msg);
14691                }
14692
14693                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14694                    ProcessRecord app = mLruProcesses.get(i);
14695                    try {
14696                        if (app.thread != null) {
14697                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14698                                    + app.processName + " new config " + mConfiguration);
14699                            app.thread.scheduleConfigurationChanged(configCopy);
14700                        }
14701                    } catch (Exception e) {
14702                    }
14703                }
14704                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14705                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14706                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14707                        | Intent.FLAG_RECEIVER_FOREGROUND);
14708                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14709                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14710                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14711                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14712                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14713                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14714                    broadcastIntentLocked(null, null, intent,
14715                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14716                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14717                }
14718            }
14719        }
14720
14721        boolean kept = true;
14722        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14723        // mainStack is null during startup.
14724        if (mainStack != null) {
14725            if (changes != 0 && starting == null) {
14726                // If the configuration changed, and the caller is not already
14727                // in the process of starting an activity, then find the top
14728                // activity to check if its configuration needs to change.
14729                starting = mainStack.topRunningActivityLocked(null);
14730            }
14731
14732            if (starting != null) {
14733                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14734                // And we need to make sure at this point that all other activities
14735                // are made visible with the correct configuration.
14736                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14737            }
14738        }
14739
14740        if (values != null && mWindowManager != null) {
14741            mWindowManager.setNewConfiguration(mConfiguration);
14742        }
14743
14744        return kept;
14745    }
14746
14747    /**
14748     * Decide based on the configuration whether we should shouw the ANR,
14749     * crash, etc dialogs.  The idea is that if there is no affordnace to
14750     * press the on-screen buttons, we shouldn't show the dialog.
14751     *
14752     * A thought: SystemUI might also want to get told about this, the Power
14753     * dialog / global actions also might want different behaviors.
14754     */
14755    private static final boolean shouldShowDialogs(Configuration config) {
14756        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14757                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14758    }
14759
14760    /**
14761     * Save the locale.  You must be inside a synchronized (this) block.
14762     */
14763    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14764        if(isDiff) {
14765            SystemProperties.set("user.language", l.getLanguage());
14766            SystemProperties.set("user.region", l.getCountry());
14767        }
14768
14769        if(isPersist) {
14770            SystemProperties.set("persist.sys.language", l.getLanguage());
14771            SystemProperties.set("persist.sys.country", l.getCountry());
14772            SystemProperties.set("persist.sys.localevar", l.getVariant());
14773        }
14774    }
14775
14776    @Override
14777    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14778        ActivityRecord srec = ActivityRecord.forToken(token);
14779        return srec != null && srec.task.affinity != null &&
14780                srec.task.affinity.equals(destAffinity);
14781    }
14782
14783    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14784            Intent resultData) {
14785
14786        synchronized (this) {
14787            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14788            if (stack != null) {
14789                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14790            }
14791            return false;
14792        }
14793    }
14794
14795    public int getLaunchedFromUid(IBinder activityToken) {
14796        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14797        if (srec == null) {
14798            return -1;
14799        }
14800        return srec.launchedFromUid;
14801    }
14802
14803    public String getLaunchedFromPackage(IBinder activityToken) {
14804        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14805        if (srec == null) {
14806            return null;
14807        }
14808        return srec.launchedFromPackage;
14809    }
14810
14811    // =========================================================
14812    // LIFETIME MANAGEMENT
14813    // =========================================================
14814
14815    // Returns which broadcast queue the app is the current [or imminent] receiver
14816    // on, or 'null' if the app is not an active broadcast recipient.
14817    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14818        BroadcastRecord r = app.curReceiver;
14819        if (r != null) {
14820            return r.queue;
14821        }
14822
14823        // It's not the current receiver, but it might be starting up to become one
14824        synchronized (this) {
14825            for (BroadcastQueue queue : mBroadcastQueues) {
14826                r = queue.mPendingBroadcast;
14827                if (r != null && r.curApp == app) {
14828                    // found it; report which queue it's in
14829                    return queue;
14830                }
14831            }
14832        }
14833
14834        return null;
14835    }
14836
14837    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14838            boolean doingAll, long now) {
14839        if (mAdjSeq == app.adjSeq) {
14840            // This adjustment has already been computed.
14841            return app.curRawAdj;
14842        }
14843
14844        if (app.thread == null) {
14845            app.adjSeq = mAdjSeq;
14846            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14847            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14848            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14849        }
14850
14851        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14852        app.adjSource = null;
14853        app.adjTarget = null;
14854        app.empty = false;
14855        app.cached = false;
14856
14857        final int activitiesSize = app.activities.size();
14858
14859        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14860            // The max adjustment doesn't allow this app to be anything
14861            // below foreground, so it is not worth doing work for it.
14862            app.adjType = "fixed";
14863            app.adjSeq = mAdjSeq;
14864            app.curRawAdj = app.maxAdj;
14865            app.foregroundActivities = false;
14866            app.keeping = true;
14867            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14868            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14869            // System processes can do UI, and when they do we want to have
14870            // them trim their memory after the user leaves the UI.  To
14871            // facilitate this, here we need to determine whether or not it
14872            // is currently showing UI.
14873            app.systemNoUi = true;
14874            if (app == TOP_APP) {
14875                app.systemNoUi = false;
14876            } else if (activitiesSize > 0) {
14877                for (int j = 0; j < activitiesSize; j++) {
14878                    final ActivityRecord r = app.activities.get(j);
14879                    if (r.visible) {
14880                        app.systemNoUi = false;
14881                    }
14882                }
14883            }
14884            if (!app.systemNoUi) {
14885                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14886            }
14887            return (app.curAdj=app.maxAdj);
14888        }
14889
14890        app.keeping = false;
14891        app.systemNoUi = false;
14892
14893        // Determine the importance of the process, starting with most
14894        // important to least, and assign an appropriate OOM adjustment.
14895        int adj;
14896        int schedGroup;
14897        int procState;
14898        boolean foregroundActivities = false;
14899        boolean interesting = false;
14900        BroadcastQueue queue;
14901        if (app == TOP_APP) {
14902            // The last app on the list is the foreground app.
14903            adj = ProcessList.FOREGROUND_APP_ADJ;
14904            schedGroup = Process.THREAD_GROUP_DEFAULT;
14905            app.adjType = "top-activity";
14906            foregroundActivities = true;
14907            interesting = true;
14908            procState = ActivityManager.PROCESS_STATE_TOP;
14909        } else if (app.instrumentationClass != null) {
14910            // Don't want to kill running instrumentation.
14911            adj = ProcessList.FOREGROUND_APP_ADJ;
14912            schedGroup = Process.THREAD_GROUP_DEFAULT;
14913            app.adjType = "instrumentation";
14914            interesting = true;
14915            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14916        } else if ((queue = isReceivingBroadcast(app)) != null) {
14917            // An app that is currently receiving a broadcast also
14918            // counts as being in the foreground for OOM killer purposes.
14919            // It's placed in a sched group based on the nature of the
14920            // broadcast as reflected by which queue it's active in.
14921            adj = ProcessList.FOREGROUND_APP_ADJ;
14922            schedGroup = (queue == mFgBroadcastQueue)
14923                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14924            app.adjType = "broadcast";
14925            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14926        } else if (app.executingServices.size() > 0) {
14927            // An app that is currently executing a service callback also
14928            // counts as being in the foreground.
14929            adj = ProcessList.FOREGROUND_APP_ADJ;
14930            schedGroup = app.execServicesFg ?
14931                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14932            app.adjType = "exec-service";
14933            procState = ActivityManager.PROCESS_STATE_SERVICE;
14934            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14935        } else {
14936            // As far as we know the process is empty.  We may change our mind later.
14937            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14938            // At this point we don't actually know the adjustment.  Use the cached adj
14939            // value that the caller wants us to.
14940            adj = cachedAdj;
14941            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14942            app.cached = true;
14943            app.empty = true;
14944            app.adjType = "cch-empty";
14945        }
14946
14947        // Examine all activities if not already foreground.
14948        if (!foregroundActivities && activitiesSize > 0) {
14949            for (int j = 0; j < activitiesSize; j++) {
14950                final ActivityRecord r = app.activities.get(j);
14951                if (r.app != app) {
14952                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14953                            + app + "?!?");
14954                    continue;
14955                }
14956                if (r.visible) {
14957                    // App has a visible activity; only upgrade adjustment.
14958                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14959                        adj = ProcessList.VISIBLE_APP_ADJ;
14960                        app.adjType = "visible";
14961                    }
14962                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14963                        procState = ActivityManager.PROCESS_STATE_TOP;
14964                    }
14965                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14966                    app.cached = false;
14967                    app.empty = false;
14968                    foregroundActivities = true;
14969                    break;
14970                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14971                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14972                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14973                        app.adjType = "pausing";
14974                    }
14975                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14976                        procState = ActivityManager.PROCESS_STATE_TOP;
14977                    }
14978                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14979                    app.cached = false;
14980                    app.empty = false;
14981                    foregroundActivities = true;
14982                } else if (r.state == ActivityState.STOPPING) {
14983                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14984                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14985                        app.adjType = "stopping";
14986                    }
14987                    // For the process state, we will at this point consider the
14988                    // process to be cached.  It will be cached either as an activity
14989                    // or empty depending on whether the activity is finishing.  We do
14990                    // this so that we can treat the process as cached for purposes of
14991                    // memory trimming (determing current memory level, trim command to
14992                    // send to process) since there can be an arbitrary number of stopping
14993                    // processes and they should soon all go into the cached state.
14994                    if (!r.finishing) {
14995                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14996                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14997                        }
14998                    }
14999                    app.cached = false;
15000                    app.empty = false;
15001                    foregroundActivities = true;
15002                } else {
15003                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15004                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15005                        app.adjType = "cch-act";
15006                    }
15007                }
15008            }
15009        }
15010
15011        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15012            if (app.foregroundServices) {
15013                // The user is aware of this app, so make it visible.
15014                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15015                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15016                app.cached = false;
15017                app.adjType = "fg-service";
15018                schedGroup = Process.THREAD_GROUP_DEFAULT;
15019            } else if (app.forcingToForeground != null) {
15020                // The user is aware of this app, so make it visible.
15021                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15022                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15023                app.cached = false;
15024                app.adjType = "force-fg";
15025                app.adjSource = app.forcingToForeground;
15026                schedGroup = Process.THREAD_GROUP_DEFAULT;
15027            }
15028        }
15029
15030        if (app.foregroundServices) {
15031            interesting = true;
15032        }
15033
15034        if (app == mHeavyWeightProcess) {
15035            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15036                // We don't want to kill the current heavy-weight process.
15037                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15038                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15039                app.cached = false;
15040                app.adjType = "heavy";
15041            }
15042            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15043                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15044            }
15045        }
15046
15047        if (app == mHomeProcess) {
15048            if (adj > ProcessList.HOME_APP_ADJ) {
15049                // This process is hosting what we currently consider to be the
15050                // home app, so we don't want to let it go into the background.
15051                adj = ProcessList.HOME_APP_ADJ;
15052                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15053                app.cached = false;
15054                app.adjType = "home";
15055            }
15056            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15057                procState = ActivityManager.PROCESS_STATE_HOME;
15058            }
15059        }
15060
15061        if (app == mPreviousProcess && app.activities.size() > 0) {
15062            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15063                // This was the previous process that showed UI to the user.
15064                // We want to try to keep it around more aggressively, to give
15065                // a good experience around switching between two apps.
15066                adj = ProcessList.PREVIOUS_APP_ADJ;
15067                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15068                app.cached = false;
15069                app.adjType = "previous";
15070            }
15071            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15072                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15073            }
15074        }
15075
15076        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15077                + " reason=" + app.adjType);
15078
15079        // By default, we use the computed adjustment.  It may be changed if
15080        // there are applications dependent on our services or providers, but
15081        // this gives us a baseline and makes sure we don't get into an
15082        // infinite recursion.
15083        app.adjSeq = mAdjSeq;
15084        app.curRawAdj = adj;
15085        app.hasStartedServices = false;
15086
15087        if (mBackupTarget != null && app == mBackupTarget.app) {
15088            // If possible we want to avoid killing apps while they're being backed up
15089            if (adj > ProcessList.BACKUP_APP_ADJ) {
15090                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15091                adj = ProcessList.BACKUP_APP_ADJ;
15092                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15093                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15094                }
15095                app.adjType = "backup";
15096                app.cached = false;
15097            }
15098            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15099                procState = ActivityManager.PROCESS_STATE_BACKUP;
15100            }
15101        }
15102
15103        boolean mayBeTop = false;
15104
15105        for (int is = app.services.size()-1;
15106                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15107                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15108                        || procState > ActivityManager.PROCESS_STATE_TOP);
15109                is--) {
15110            ServiceRecord s = app.services.valueAt(is);
15111            if (s.startRequested) {
15112                app.hasStartedServices = true;
15113                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15114                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15115                }
15116                if (app.hasShownUi && app != mHomeProcess) {
15117                    // If this process has shown some UI, let it immediately
15118                    // go to the LRU list because it may be pretty heavy with
15119                    // UI stuff.  We'll tag it with a label just to help
15120                    // debug and understand what is going on.
15121                    if (adj > ProcessList.SERVICE_ADJ) {
15122                        app.adjType = "cch-started-ui-services";
15123                    }
15124                } else {
15125                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15126                        // This service has seen some activity within
15127                        // recent memory, so we will keep its process ahead
15128                        // of the background processes.
15129                        if (adj > ProcessList.SERVICE_ADJ) {
15130                            adj = ProcessList.SERVICE_ADJ;
15131                            app.adjType = "started-services";
15132                            app.cached = false;
15133                        }
15134                    }
15135                    // If we have let the service slide into the background
15136                    // state, still have some text describing what it is doing
15137                    // even though the service no longer has an impact.
15138                    if (adj > ProcessList.SERVICE_ADJ) {
15139                        app.adjType = "cch-started-services";
15140                    }
15141                }
15142                // Don't kill this process because it is doing work; it
15143                // has said it is doing work.
15144                app.keeping = true;
15145            }
15146            for (int conni = s.connections.size()-1;
15147                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15148                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15149                            || procState > ActivityManager.PROCESS_STATE_TOP);
15150                    conni--) {
15151                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15152                for (int i = 0;
15153                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15154                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15155                                || procState > ActivityManager.PROCESS_STATE_TOP);
15156                        i++) {
15157                    // XXX should compute this based on the max of
15158                    // all connected clients.
15159                    ConnectionRecord cr = clist.get(i);
15160                    if (cr.binding.client == app) {
15161                        // Binding to ourself is not interesting.
15162                        continue;
15163                    }
15164                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15165                        ProcessRecord client = cr.binding.client;
15166                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15167                                TOP_APP, doingAll, now);
15168                        int clientProcState = client.curProcState;
15169                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15170                            // If the other app is cached for any reason, for purposes here
15171                            // we are going to consider it empty.  The specific cached state
15172                            // doesn't propagate except under certain conditions.
15173                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15174                        }
15175                        String adjType = null;
15176                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15177                            // Not doing bind OOM management, so treat
15178                            // this guy more like a started service.
15179                            if (app.hasShownUi && app != mHomeProcess) {
15180                                // If this process has shown some UI, let it immediately
15181                                // go to the LRU list because it may be pretty heavy with
15182                                // UI stuff.  We'll tag it with a label just to help
15183                                // debug and understand what is going on.
15184                                if (adj > clientAdj) {
15185                                    adjType = "cch-bound-ui-services";
15186                                }
15187                                app.cached = false;
15188                                clientAdj = adj;
15189                                clientProcState = procState;
15190                            } else {
15191                                if (now >= (s.lastActivity
15192                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15193                                    // This service has not seen activity within
15194                                    // recent memory, so allow it to drop to the
15195                                    // LRU list if there is no other reason to keep
15196                                    // it around.  We'll also tag it with a label just
15197                                    // to help debug and undertand what is going on.
15198                                    if (adj > clientAdj) {
15199                                        adjType = "cch-bound-services";
15200                                    }
15201                                    clientAdj = adj;
15202                                }
15203                            }
15204                        }
15205                        if (adj > clientAdj) {
15206                            // If this process has recently shown UI, and
15207                            // the process that is binding to it is less
15208                            // important than being visible, then we don't
15209                            // care about the binding as much as we care
15210                            // about letting this process get into the LRU
15211                            // list to be killed and restarted if needed for
15212                            // memory.
15213                            if (app.hasShownUi && app != mHomeProcess
15214                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15215                                adjType = "cch-bound-ui-services";
15216                            } else {
15217                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15218                                        |Context.BIND_IMPORTANT)) != 0) {
15219                                    adj = clientAdj;
15220                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15221                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15222                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15223                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15224                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15225                                    adj = clientAdj;
15226                                } else {
15227                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15228                                        adj = ProcessList.VISIBLE_APP_ADJ;
15229                                    }
15230                                }
15231                                if (!client.cached) {
15232                                    app.cached = false;
15233                                }
15234                                if (client.keeping) {
15235                                    app.keeping = true;
15236                                }
15237                                adjType = "service";
15238                            }
15239                        }
15240                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15241                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15242                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15243                            }
15244                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15245                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15246                                    // Special handling of clients who are in the top state.
15247                                    // We *may* want to consider this process to be in the
15248                                    // top state as well, but only if there is not another
15249                                    // reason for it to be running.  Being on the top is a
15250                                    // special state, meaning you are specifically running
15251                                    // for the current top app.  If the process is already
15252                                    // running in the background for some other reason, it
15253                                    // is more important to continue considering it to be
15254                                    // in the background state.
15255                                    mayBeTop = true;
15256                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15257                                } else {
15258                                    // Special handling for above-top states (persistent
15259                                    // processes).  These should not bring the current process
15260                                    // into the top state, since they are not on top.  Instead
15261                                    // give them the best state after that.
15262                                    clientProcState =
15263                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15264                                }
15265                            }
15266                        } else {
15267                            if (clientProcState <
15268                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15269                                clientProcState =
15270                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15271                            }
15272                        }
15273                        if (procState > clientProcState) {
15274                            procState = clientProcState;
15275                        }
15276                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15277                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15278                            app.pendingUiClean = true;
15279                        }
15280                        if (adjType != null) {
15281                            app.adjType = adjType;
15282                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15283                                    .REASON_SERVICE_IN_USE;
15284                            app.adjSource = cr.binding.client;
15285                            app.adjSourceOom = clientAdj;
15286                            app.adjTarget = s.name;
15287                        }
15288                    }
15289                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15290                        app.treatLikeActivity = true;
15291                    }
15292                    final ActivityRecord a = cr.activity;
15293                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15294                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15295                                (a.visible || a.state == ActivityState.RESUMED
15296                                 || a.state == ActivityState.PAUSING)) {
15297                            adj = ProcessList.FOREGROUND_APP_ADJ;
15298                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15299                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15300                            }
15301                            app.cached = false;
15302                            app.adjType = "service";
15303                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15304                                    .REASON_SERVICE_IN_USE;
15305                            app.adjSource = a;
15306                            app.adjSourceOom = adj;
15307                            app.adjTarget = s.name;
15308                        }
15309                    }
15310                }
15311            }
15312        }
15313
15314        for (int provi = app.pubProviders.size()-1;
15315                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15316                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15317                        || procState > ActivityManager.PROCESS_STATE_TOP);
15318                provi--) {
15319            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15320            for (int i = cpr.connections.size()-1;
15321                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15322                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15323                            || procState > ActivityManager.PROCESS_STATE_TOP);
15324                    i--) {
15325                ContentProviderConnection conn = cpr.connections.get(i);
15326                ProcessRecord client = conn.client;
15327                if (client == app) {
15328                    // Being our own client is not interesting.
15329                    continue;
15330                }
15331                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15332                int clientProcState = client.curProcState;
15333                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15334                    // If the other app is cached for any reason, for purposes here
15335                    // we are going to consider it empty.
15336                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15337                }
15338                if (adj > clientAdj) {
15339                    if (app.hasShownUi && app != mHomeProcess
15340                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15341                        app.adjType = "cch-ui-provider";
15342                    } else {
15343                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15344                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15345                        app.adjType = "provider";
15346                    }
15347                    app.cached &= client.cached;
15348                    app.keeping |= client.keeping;
15349                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15350                            .REASON_PROVIDER_IN_USE;
15351                    app.adjSource = client;
15352                    app.adjSourceOom = clientAdj;
15353                    app.adjTarget = cpr.name;
15354                }
15355                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15356                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15357                        // Special handling of clients who are in the top state.
15358                        // We *may* want to consider this process to be in the
15359                        // top state as well, but only if there is not another
15360                        // reason for it to be running.  Being on the top is a
15361                        // special state, meaning you are specifically running
15362                        // for the current top app.  If the process is already
15363                        // running in the background for some other reason, it
15364                        // is more important to continue considering it to be
15365                        // in the background state.
15366                        mayBeTop = true;
15367                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15368                    } else {
15369                        // Special handling for above-top states (persistent
15370                        // processes).  These should not bring the current process
15371                        // into the top state, since they are not on top.  Instead
15372                        // give them the best state after that.
15373                        clientProcState =
15374                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15375                    }
15376                }
15377                if (procState > clientProcState) {
15378                    procState = clientProcState;
15379                }
15380                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15381                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15382                }
15383            }
15384            // If the provider has external (non-framework) process
15385            // dependencies, ensure that its adjustment is at least
15386            // FOREGROUND_APP_ADJ.
15387            if (cpr.hasExternalProcessHandles()) {
15388                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15389                    adj = ProcessList.FOREGROUND_APP_ADJ;
15390                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15391                    app.cached = false;
15392                    app.keeping = true;
15393                    app.adjType = "provider";
15394                    app.adjTarget = cpr.name;
15395                }
15396                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15397                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15398                }
15399            }
15400        }
15401
15402        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15403            // A client of one of our services or providers is in the top state.  We
15404            // *may* want to be in the top state, but not if we are already running in
15405            // the background for some other reason.  For the decision here, we are going
15406            // to pick out a few specific states that we want to remain in when a client
15407            // is top (states that tend to be longer-term) and otherwise allow it to go
15408            // to the top state.
15409            switch (procState) {
15410                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15411                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15412                case ActivityManager.PROCESS_STATE_SERVICE:
15413                    // These all are longer-term states, so pull them up to the top
15414                    // of the background states, but not all the way to the top state.
15415                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15416                    break;
15417                default:
15418                    // Otherwise, top is a better choice, so take it.
15419                    procState = ActivityManager.PROCESS_STATE_TOP;
15420                    break;
15421            }
15422        }
15423
15424        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15425            if (app.hasClientActivities) {
15426                // This is a cached process, but with client activities.  Mark it so.
15427                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15428                app.adjType = "cch-client-act";
15429            } else if (app.treatLikeActivity) {
15430                // This is a cached process, but somebody wants us to treat it like it has
15431                // an activity, okay!
15432                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15433                app.adjType = "cch-as-act";
15434            }
15435        }
15436
15437        if (adj == ProcessList.SERVICE_ADJ) {
15438            if (doingAll) {
15439                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15440                mNewNumServiceProcs++;
15441                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15442                if (!app.serviceb) {
15443                    // This service isn't far enough down on the LRU list to
15444                    // normally be a B service, but if we are low on RAM and it
15445                    // is large we want to force it down since we would prefer to
15446                    // keep launcher over it.
15447                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15448                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15449                        app.serviceHighRam = true;
15450                        app.serviceb = true;
15451                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15452                    } else {
15453                        mNewNumAServiceProcs++;
15454                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15455                    }
15456                } else {
15457                    app.serviceHighRam = false;
15458                }
15459            }
15460            if (app.serviceb) {
15461                adj = ProcessList.SERVICE_B_ADJ;
15462            }
15463        }
15464
15465        app.curRawAdj = adj;
15466
15467        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15468        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15469        if (adj > app.maxAdj) {
15470            adj = app.maxAdj;
15471            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15472                schedGroup = Process.THREAD_GROUP_DEFAULT;
15473            }
15474        }
15475        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15476            app.keeping = true;
15477        }
15478
15479        // Do final modification to adj.  Everything we do between here and applying
15480        // the final setAdj must be done in this function, because we will also use
15481        // it when computing the final cached adj later.  Note that we don't need to
15482        // worry about this for max adj above, since max adj will always be used to
15483        // keep it out of the cached vaues.
15484        app.curAdj = app.modifyRawOomAdj(adj);
15485        app.curSchedGroup = schedGroup;
15486        app.curProcState = procState;
15487        app.foregroundActivities = foregroundActivities;
15488
15489        return app.curRawAdj;
15490    }
15491
15492    /**
15493     * Schedule PSS collection of a process.
15494     */
15495    void requestPssLocked(ProcessRecord proc, int procState) {
15496        if (mPendingPssProcesses.contains(proc)) {
15497            return;
15498        }
15499        if (mPendingPssProcesses.size() == 0) {
15500            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15501        }
15502        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15503        proc.pssProcState = procState;
15504        mPendingPssProcesses.add(proc);
15505    }
15506
15507    /**
15508     * Schedule PSS collection of all processes.
15509     */
15510    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15511        if (!always) {
15512            if (now < (mLastFullPssTime +
15513                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15514                return;
15515            }
15516        }
15517        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15518        mLastFullPssTime = now;
15519        mFullPssPending = true;
15520        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15521        mPendingPssProcesses.clear();
15522        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15523            ProcessRecord app = mLruProcesses.get(i);
15524            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15525                app.pssProcState = app.setProcState;
15526                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15527                        isSleeping(), now);
15528                mPendingPssProcesses.add(app);
15529            }
15530        }
15531        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15532    }
15533
15534    /**
15535     * Ask a given process to GC right now.
15536     */
15537    final void performAppGcLocked(ProcessRecord app) {
15538        try {
15539            app.lastRequestedGc = SystemClock.uptimeMillis();
15540            if (app.thread != null) {
15541                if (app.reportLowMemory) {
15542                    app.reportLowMemory = false;
15543                    app.thread.scheduleLowMemory();
15544                } else {
15545                    app.thread.processInBackground();
15546                }
15547            }
15548        } catch (Exception e) {
15549            // whatever.
15550        }
15551    }
15552
15553    /**
15554     * Returns true if things are idle enough to perform GCs.
15555     */
15556    private final boolean canGcNowLocked() {
15557        boolean processingBroadcasts = false;
15558        for (BroadcastQueue q : mBroadcastQueues) {
15559            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15560                processingBroadcasts = true;
15561            }
15562        }
15563        return !processingBroadcasts
15564                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15565    }
15566
15567    /**
15568     * Perform GCs on all processes that are waiting for it, but only
15569     * if things are idle.
15570     */
15571    final void performAppGcsLocked() {
15572        final int N = mProcessesToGc.size();
15573        if (N <= 0) {
15574            return;
15575        }
15576        if (canGcNowLocked()) {
15577            while (mProcessesToGc.size() > 0) {
15578                ProcessRecord proc = mProcessesToGc.remove(0);
15579                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15580                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15581                            <= SystemClock.uptimeMillis()) {
15582                        // To avoid spamming the system, we will GC processes one
15583                        // at a time, waiting a few seconds between each.
15584                        performAppGcLocked(proc);
15585                        scheduleAppGcsLocked();
15586                        return;
15587                    } else {
15588                        // It hasn't been long enough since we last GCed this
15589                        // process...  put it in the list to wait for its time.
15590                        addProcessToGcListLocked(proc);
15591                        break;
15592                    }
15593                }
15594            }
15595
15596            scheduleAppGcsLocked();
15597        }
15598    }
15599
15600    /**
15601     * If all looks good, perform GCs on all processes waiting for them.
15602     */
15603    final void performAppGcsIfAppropriateLocked() {
15604        if (canGcNowLocked()) {
15605            performAppGcsLocked();
15606            return;
15607        }
15608        // Still not idle, wait some more.
15609        scheduleAppGcsLocked();
15610    }
15611
15612    /**
15613     * Schedule the execution of all pending app GCs.
15614     */
15615    final void scheduleAppGcsLocked() {
15616        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15617
15618        if (mProcessesToGc.size() > 0) {
15619            // Schedule a GC for the time to the next process.
15620            ProcessRecord proc = mProcessesToGc.get(0);
15621            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15622
15623            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15624            long now = SystemClock.uptimeMillis();
15625            if (when < (now+GC_TIMEOUT)) {
15626                when = now + GC_TIMEOUT;
15627            }
15628            mHandler.sendMessageAtTime(msg, when);
15629        }
15630    }
15631
15632    /**
15633     * Add a process to the array of processes waiting to be GCed.  Keeps the
15634     * list in sorted order by the last GC time.  The process can't already be
15635     * on the list.
15636     */
15637    final void addProcessToGcListLocked(ProcessRecord proc) {
15638        boolean added = false;
15639        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15640            if (mProcessesToGc.get(i).lastRequestedGc <
15641                    proc.lastRequestedGc) {
15642                added = true;
15643                mProcessesToGc.add(i+1, proc);
15644                break;
15645            }
15646        }
15647        if (!added) {
15648            mProcessesToGc.add(0, proc);
15649        }
15650    }
15651
15652    /**
15653     * Set up to ask a process to GC itself.  This will either do it
15654     * immediately, or put it on the list of processes to gc the next
15655     * time things are idle.
15656     */
15657    final void scheduleAppGcLocked(ProcessRecord app) {
15658        long now = SystemClock.uptimeMillis();
15659        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15660            return;
15661        }
15662        if (!mProcessesToGc.contains(app)) {
15663            addProcessToGcListLocked(app);
15664            scheduleAppGcsLocked();
15665        }
15666    }
15667
15668    final void checkExcessivePowerUsageLocked(boolean doKills) {
15669        updateCpuStatsNow();
15670
15671        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15672        boolean doWakeKills = doKills;
15673        boolean doCpuKills = doKills;
15674        if (mLastPowerCheckRealtime == 0) {
15675            doWakeKills = false;
15676        }
15677        if (mLastPowerCheckUptime == 0) {
15678            doCpuKills = false;
15679        }
15680        if (stats.isScreenOn()) {
15681            doWakeKills = false;
15682        }
15683        final long curRealtime = SystemClock.elapsedRealtime();
15684        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15685        final long curUptime = SystemClock.uptimeMillis();
15686        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15687        mLastPowerCheckRealtime = curRealtime;
15688        mLastPowerCheckUptime = curUptime;
15689        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15690            doWakeKills = false;
15691        }
15692        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15693            doCpuKills = false;
15694        }
15695        int i = mLruProcesses.size();
15696        while (i > 0) {
15697            i--;
15698            ProcessRecord app = mLruProcesses.get(i);
15699            if (!app.keeping) {
15700                long wtime;
15701                synchronized (stats) {
15702                    wtime = stats.getProcessWakeTime(app.info.uid,
15703                            app.pid, curRealtime);
15704                }
15705                long wtimeUsed = wtime - app.lastWakeTime;
15706                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15707                if (DEBUG_POWER) {
15708                    StringBuilder sb = new StringBuilder(128);
15709                    sb.append("Wake for ");
15710                    app.toShortString(sb);
15711                    sb.append(": over ");
15712                    TimeUtils.formatDuration(realtimeSince, sb);
15713                    sb.append(" used ");
15714                    TimeUtils.formatDuration(wtimeUsed, sb);
15715                    sb.append(" (");
15716                    sb.append((wtimeUsed*100)/realtimeSince);
15717                    sb.append("%)");
15718                    Slog.i(TAG, sb.toString());
15719                    sb.setLength(0);
15720                    sb.append("CPU for ");
15721                    app.toShortString(sb);
15722                    sb.append(": over ");
15723                    TimeUtils.formatDuration(uptimeSince, sb);
15724                    sb.append(" used ");
15725                    TimeUtils.formatDuration(cputimeUsed, sb);
15726                    sb.append(" (");
15727                    sb.append((cputimeUsed*100)/uptimeSince);
15728                    sb.append("%)");
15729                    Slog.i(TAG, sb.toString());
15730                }
15731                // If a process has held a wake lock for more
15732                // than 50% of the time during this period,
15733                // that sounds bad.  Kill!
15734                if (doWakeKills && realtimeSince > 0
15735                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15736                    synchronized (stats) {
15737                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15738                                realtimeSince, wtimeUsed);
15739                    }
15740                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15741                            + " during " + realtimeSince);
15742                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15743                } else if (doCpuKills && uptimeSince > 0
15744                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15745                    synchronized (stats) {
15746                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15747                                uptimeSince, cputimeUsed);
15748                    }
15749                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15750                            + " during " + uptimeSince);
15751                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15752                } else {
15753                    app.lastWakeTime = wtime;
15754                    app.lastCpuTime = app.curCpuTime;
15755                }
15756            }
15757        }
15758    }
15759
15760    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15761            ProcessRecord TOP_APP, boolean doingAll, long now) {
15762        boolean success = true;
15763
15764        if (app.curRawAdj != app.setRawAdj) {
15765            if (wasKeeping && !app.keeping) {
15766                // This app is no longer something we want to keep.  Note
15767                // its current wake lock time to later know to kill it if
15768                // it is not behaving well.
15769                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15770                synchronized (stats) {
15771                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15772                            app.pid, SystemClock.elapsedRealtime());
15773                }
15774                app.lastCpuTime = app.curCpuTime;
15775            }
15776
15777            app.setRawAdj = app.curRawAdj;
15778        }
15779
15780        int changes = 0;
15781
15782        if (app.curAdj != app.setAdj) {
15783            ProcessList.setOomAdj(app.pid, app.curAdj);
15784            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15785                TAG, "Set " + app.pid + " " + app.processName +
15786                " adj " + app.curAdj + ": " + app.adjType);
15787            app.setAdj = app.curAdj;
15788        }
15789
15790        if (app.setSchedGroup != app.curSchedGroup) {
15791            app.setSchedGroup = app.curSchedGroup;
15792            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15793                    "Setting process group of " + app.processName
15794                    + " to " + app.curSchedGroup);
15795            if (app.waitingToKill != null &&
15796                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15797                killUnneededProcessLocked(app, app.waitingToKill);
15798                success = false;
15799            } else {
15800                if (true) {
15801                    long oldId = Binder.clearCallingIdentity();
15802                    try {
15803                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15804                    } catch (Exception e) {
15805                        Slog.w(TAG, "Failed setting process group of " + app.pid
15806                                + " to " + app.curSchedGroup);
15807                        e.printStackTrace();
15808                    } finally {
15809                        Binder.restoreCallingIdentity(oldId);
15810                    }
15811                } else {
15812                    if (app.thread != null) {
15813                        try {
15814                            app.thread.setSchedulingGroup(app.curSchedGroup);
15815                        } catch (RemoteException e) {
15816                        }
15817                    }
15818                }
15819                Process.setSwappiness(app.pid,
15820                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15821            }
15822        }
15823        if (app.repForegroundActivities != app.foregroundActivities) {
15824            app.repForegroundActivities = app.foregroundActivities;
15825            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15826        }
15827        if (app.repProcState != app.curProcState) {
15828            app.repProcState = app.curProcState;
15829            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15830            if (app.thread != null) {
15831                try {
15832                    if (false) {
15833                        //RuntimeException h = new RuntimeException("here");
15834                        Slog.i(TAG, "Sending new process state " + app.repProcState
15835                                + " to " + app /*, h*/);
15836                    }
15837                    app.thread.setProcessState(app.repProcState);
15838                } catch (RemoteException e) {
15839                }
15840            }
15841        }
15842        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15843                app.setProcState)) {
15844            app.lastStateTime = now;
15845            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15846                    isSleeping(), now);
15847            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15848                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15849                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15850                    + (app.nextPssTime-now) + ": " + app);
15851        } else {
15852            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15853                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15854                requestPssLocked(app, app.setProcState);
15855                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15856                        isSleeping(), now);
15857            } else if (false && DEBUG_PSS) {
15858                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15859            }
15860        }
15861        if (app.setProcState != app.curProcState) {
15862            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15863                    "Proc state change of " + app.processName
15864                    + " to " + app.curProcState);
15865            app.setProcState = app.curProcState;
15866            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15867                app.notCachedSinceIdle = false;
15868            }
15869            if (!doingAll) {
15870                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15871            } else {
15872                app.procStateChanged = true;
15873            }
15874        }
15875
15876        if (changes != 0) {
15877            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15878            int i = mPendingProcessChanges.size()-1;
15879            ProcessChangeItem item = null;
15880            while (i >= 0) {
15881                item = mPendingProcessChanges.get(i);
15882                if (item.pid == app.pid) {
15883                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15884                    break;
15885                }
15886                i--;
15887            }
15888            if (i < 0) {
15889                // No existing item in pending changes; need a new one.
15890                final int NA = mAvailProcessChanges.size();
15891                if (NA > 0) {
15892                    item = mAvailProcessChanges.remove(NA-1);
15893                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15894                } else {
15895                    item = new ProcessChangeItem();
15896                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15897                }
15898                item.changes = 0;
15899                item.pid = app.pid;
15900                item.uid = app.info.uid;
15901                if (mPendingProcessChanges.size() == 0) {
15902                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15903                            "*** Enqueueing dispatch processes changed!");
15904                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15905                }
15906                mPendingProcessChanges.add(item);
15907            }
15908            item.changes |= changes;
15909            item.processState = app.repProcState;
15910            item.foregroundActivities = app.repForegroundActivities;
15911            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15912                    + Integer.toHexString(System.identityHashCode(item))
15913                    + " " + app.toShortString() + ": changes=" + item.changes
15914                    + " procState=" + item.processState
15915                    + " foreground=" + item.foregroundActivities
15916                    + " type=" + app.adjType + " source=" + app.adjSource
15917                    + " target=" + app.adjTarget);
15918        }
15919
15920        return success;
15921    }
15922
15923    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15924        if (proc.thread != null && proc.baseProcessTracker != null) {
15925            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15926        }
15927    }
15928
15929    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15930            ProcessRecord TOP_APP, boolean doingAll, long now) {
15931        if (app.thread == null) {
15932            return false;
15933        }
15934
15935        final boolean wasKeeping = app.keeping;
15936
15937        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15938
15939        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15940    }
15941
15942    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15943            boolean oomAdj) {
15944        if (isForeground != proc.foregroundServices) {
15945            proc.foregroundServices = isForeground;
15946            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15947                    proc.info.uid);
15948            if (isForeground) {
15949                if (curProcs == null) {
15950                    curProcs = new ArrayList<ProcessRecord>();
15951                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15952                }
15953                if (!curProcs.contains(proc)) {
15954                    curProcs.add(proc);
15955                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15956                            proc.info.packageName, proc.info.uid);
15957                }
15958            } else {
15959                if (curProcs != null) {
15960                    if (curProcs.remove(proc)) {
15961                        mBatteryStatsService.noteEvent(
15962                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15963                                proc.info.packageName, proc.info.uid);
15964                        if (curProcs.size() <= 0) {
15965                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15966                        }
15967                    }
15968                }
15969            }
15970            if (oomAdj) {
15971                updateOomAdjLocked();
15972            }
15973        }
15974    }
15975
15976    private final ActivityRecord resumedAppLocked() {
15977        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15978        String pkg;
15979        int uid;
15980        if (act != null && !act.sleeping) {
15981            pkg = act.packageName;
15982            uid = act.info.applicationInfo.uid;
15983        } else {
15984            pkg = null;
15985            uid = -1;
15986        }
15987        // Has the UID or resumed package name changed?
15988        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15989                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15990            if (mCurResumedPackage != null) {
15991                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15992                        mCurResumedPackage, mCurResumedUid);
15993            }
15994            mCurResumedPackage = pkg;
15995            mCurResumedUid = uid;
15996            if (mCurResumedPackage != null) {
15997                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15998                        mCurResumedPackage, mCurResumedUid);
15999            }
16000        }
16001        return act;
16002    }
16003
16004    final boolean updateOomAdjLocked(ProcessRecord app) {
16005        final ActivityRecord TOP_ACT = resumedAppLocked();
16006        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16007        final boolean wasCached = app.cached;
16008
16009        mAdjSeq++;
16010
16011        // This is the desired cached adjusment we want to tell it to use.
16012        // If our app is currently cached, we know it, and that is it.  Otherwise,
16013        // we don't know it yet, and it needs to now be cached we will then
16014        // need to do a complete oom adj.
16015        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16016                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16017        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16018                SystemClock.uptimeMillis());
16019        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16020            // Changed to/from cached state, so apps after it in the LRU
16021            // list may also be changed.
16022            updateOomAdjLocked();
16023        }
16024        return success;
16025    }
16026
16027    final void updateOomAdjLocked() {
16028        final ActivityRecord TOP_ACT = resumedAppLocked();
16029        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16030        final long now = SystemClock.uptimeMillis();
16031        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16032        final int N = mLruProcesses.size();
16033
16034        if (false) {
16035            RuntimeException e = new RuntimeException();
16036            e.fillInStackTrace();
16037            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16038        }
16039
16040        mAdjSeq++;
16041        mNewNumServiceProcs = 0;
16042        mNewNumAServiceProcs = 0;
16043
16044        final int emptyProcessLimit;
16045        final int cachedProcessLimit;
16046        if (mProcessLimit <= 0) {
16047            emptyProcessLimit = cachedProcessLimit = 0;
16048        } else if (mProcessLimit == 1) {
16049            emptyProcessLimit = 1;
16050            cachedProcessLimit = 0;
16051        } else {
16052            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16053            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16054        }
16055
16056        // Let's determine how many processes we have running vs.
16057        // how many slots we have for background processes; we may want
16058        // to put multiple processes in a slot of there are enough of
16059        // them.
16060        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16061                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16062        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16063        if (numEmptyProcs > cachedProcessLimit) {
16064            // If there are more empty processes than our limit on cached
16065            // processes, then use the cached process limit for the factor.
16066            // This ensures that the really old empty processes get pushed
16067            // down to the bottom, so if we are running low on memory we will
16068            // have a better chance at keeping around more cached processes
16069            // instead of a gazillion empty processes.
16070            numEmptyProcs = cachedProcessLimit;
16071        }
16072        int emptyFactor = numEmptyProcs/numSlots;
16073        if (emptyFactor < 1) emptyFactor = 1;
16074        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16075        if (cachedFactor < 1) cachedFactor = 1;
16076        int stepCached = 0;
16077        int stepEmpty = 0;
16078        int numCached = 0;
16079        int numEmpty = 0;
16080        int numTrimming = 0;
16081
16082        mNumNonCachedProcs = 0;
16083        mNumCachedHiddenProcs = 0;
16084
16085        // First update the OOM adjustment for each of the
16086        // application processes based on their current state.
16087        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16088        int nextCachedAdj = curCachedAdj+1;
16089        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16090        int nextEmptyAdj = curEmptyAdj+2;
16091        for (int i=N-1; i>=0; i--) {
16092            ProcessRecord app = mLruProcesses.get(i);
16093            if (!app.killedByAm && app.thread != null) {
16094                app.procStateChanged = false;
16095                final boolean wasKeeping = app.keeping;
16096                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16097
16098                // If we haven't yet assigned the final cached adj
16099                // to the process, do that now.
16100                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16101                    switch (app.curProcState) {
16102                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16103                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16104                            // This process is a cached process holding activities...
16105                            // assign it the next cached value for that type, and then
16106                            // step that cached level.
16107                            app.curRawAdj = curCachedAdj;
16108                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16109                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16110                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16111                                    + ")");
16112                            if (curCachedAdj != nextCachedAdj) {
16113                                stepCached++;
16114                                if (stepCached >= cachedFactor) {
16115                                    stepCached = 0;
16116                                    curCachedAdj = nextCachedAdj;
16117                                    nextCachedAdj += 2;
16118                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16119                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16120                                    }
16121                                }
16122                            }
16123                            break;
16124                        default:
16125                            // For everything else, assign next empty cached process
16126                            // level and bump that up.  Note that this means that
16127                            // long-running services that have dropped down to the
16128                            // cached level will be treated as empty (since their process
16129                            // state is still as a service), which is what we want.
16130                            app.curRawAdj = curEmptyAdj;
16131                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16132                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16133                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16134                                    + ")");
16135                            if (curEmptyAdj != nextEmptyAdj) {
16136                                stepEmpty++;
16137                                if (stepEmpty >= emptyFactor) {
16138                                    stepEmpty = 0;
16139                                    curEmptyAdj = nextEmptyAdj;
16140                                    nextEmptyAdj += 2;
16141                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16142                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16143                                    }
16144                                }
16145                            }
16146                            break;
16147                    }
16148                }
16149
16150                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16151
16152                // Count the number of process types.
16153                switch (app.curProcState) {
16154                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16155                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16156                        mNumCachedHiddenProcs++;
16157                        numCached++;
16158                        if (numCached > cachedProcessLimit) {
16159                            killUnneededProcessLocked(app, "cached #" + numCached);
16160                        }
16161                        break;
16162                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16163                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16164                                && app.lastActivityTime < oldTime) {
16165                            killUnneededProcessLocked(app, "empty for "
16166                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16167                                    / 1000) + "s");
16168                        } else {
16169                            numEmpty++;
16170                            if (numEmpty > emptyProcessLimit) {
16171                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16172                            }
16173                        }
16174                        break;
16175                    default:
16176                        mNumNonCachedProcs++;
16177                        break;
16178                }
16179
16180                if (app.isolated && app.services.size() <= 0) {
16181                    // If this is an isolated process, and there are no
16182                    // services running in it, then the process is no longer
16183                    // needed.  We agressively kill these because we can by
16184                    // definition not re-use the same process again, and it is
16185                    // good to avoid having whatever code was running in them
16186                    // left sitting around after no longer needed.
16187                    killUnneededProcessLocked(app, "isolated not needed");
16188                }
16189
16190                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16191                        && !app.killedByAm) {
16192                    numTrimming++;
16193                }
16194            }
16195        }
16196
16197        mNumServiceProcs = mNewNumServiceProcs;
16198
16199        // Now determine the memory trimming level of background processes.
16200        // Unfortunately we need to start at the back of the list to do this
16201        // properly.  We only do this if the number of background apps we
16202        // are managing to keep around is less than half the maximum we desire;
16203        // if we are keeping a good number around, we'll let them use whatever
16204        // memory they want.
16205        final int numCachedAndEmpty = numCached + numEmpty;
16206        int memFactor;
16207        if (numCached <= ProcessList.TRIM_CACHED_APPS
16208                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16209            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16210                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16211            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16212                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16213            } else {
16214                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16215            }
16216        } else {
16217            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16218        }
16219        // We always allow the memory level to go up (better).  We only allow it to go
16220        // down if we are in a state where that is allowed, *and* the total number of processes
16221        // has gone down since last time.
16222        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16223                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16224                + " last=" + mLastNumProcesses);
16225        if (memFactor > mLastMemoryLevel) {
16226            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16227                memFactor = mLastMemoryLevel;
16228                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16229            }
16230        }
16231        mLastMemoryLevel = memFactor;
16232        mLastNumProcesses = mLruProcesses.size();
16233        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16234        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16235        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16236            if (mLowRamStartTime == 0) {
16237                mLowRamStartTime = now;
16238            }
16239            int step = 0;
16240            int fgTrimLevel;
16241            switch (memFactor) {
16242                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16243                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16244                    break;
16245                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16246                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16247                    break;
16248                default:
16249                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16250                    break;
16251            }
16252            int factor = numTrimming/3;
16253            int minFactor = 2;
16254            if (mHomeProcess != null) minFactor++;
16255            if (mPreviousProcess != null) minFactor++;
16256            if (factor < minFactor) factor = minFactor;
16257            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16258            for (int i=N-1; i>=0; i--) {
16259                ProcessRecord app = mLruProcesses.get(i);
16260                if (allChanged || app.procStateChanged) {
16261                    setProcessTrackerState(app, trackerMemFactor, now);
16262                    app.procStateChanged = false;
16263                }
16264                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16265                        && !app.killedByAm) {
16266                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16267                        try {
16268                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16269                                    "Trimming memory of " + app.processName
16270                                    + " to " + curLevel);
16271                            app.thread.scheduleTrimMemory(curLevel);
16272                        } catch (RemoteException e) {
16273                        }
16274                        if (false) {
16275                            // For now we won't do this; our memory trimming seems
16276                            // to be good enough at this point that destroying
16277                            // activities causes more harm than good.
16278                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16279                                    && app != mHomeProcess && app != mPreviousProcess) {
16280                                // Need to do this on its own message because the stack may not
16281                                // be in a consistent state at this point.
16282                                // For these apps we will also finish their activities
16283                                // to help them free memory.
16284                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16285                            }
16286                        }
16287                    }
16288                    app.trimMemoryLevel = curLevel;
16289                    step++;
16290                    if (step >= factor) {
16291                        step = 0;
16292                        switch (curLevel) {
16293                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16294                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16295                                break;
16296                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16297                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16298                                break;
16299                        }
16300                    }
16301                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16302                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16303                            && app.thread != null) {
16304                        try {
16305                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16306                                    "Trimming memory of heavy-weight " + app.processName
16307                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16308                            app.thread.scheduleTrimMemory(
16309                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16310                        } catch (RemoteException e) {
16311                        }
16312                    }
16313                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16314                } else {
16315                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16316                            || app.systemNoUi) && app.pendingUiClean) {
16317                        // If this application is now in the background and it
16318                        // had done UI, then give it the special trim level to
16319                        // have it free UI resources.
16320                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16321                        if (app.trimMemoryLevel < level && app.thread != null) {
16322                            try {
16323                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16324                                        "Trimming memory of bg-ui " + app.processName
16325                                        + " to " + level);
16326                                app.thread.scheduleTrimMemory(level);
16327                            } catch (RemoteException e) {
16328                            }
16329                        }
16330                        app.pendingUiClean = false;
16331                    }
16332                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16333                        try {
16334                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16335                                    "Trimming memory of fg " + app.processName
16336                                    + " to " + fgTrimLevel);
16337                            app.thread.scheduleTrimMemory(fgTrimLevel);
16338                        } catch (RemoteException e) {
16339                        }
16340                    }
16341                    app.trimMemoryLevel = fgTrimLevel;
16342                }
16343            }
16344        } else {
16345            if (mLowRamStartTime != 0) {
16346                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16347                mLowRamStartTime = 0;
16348            }
16349            for (int i=N-1; i>=0; i--) {
16350                ProcessRecord app = mLruProcesses.get(i);
16351                if (allChanged || app.procStateChanged) {
16352                    setProcessTrackerState(app, trackerMemFactor, now);
16353                    app.procStateChanged = false;
16354                }
16355                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16356                        || app.systemNoUi) && app.pendingUiClean) {
16357                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16358                            && app.thread != null) {
16359                        try {
16360                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16361                                    "Trimming memory of ui hidden " + app.processName
16362                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16363                            app.thread.scheduleTrimMemory(
16364                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16365                        } catch (RemoteException e) {
16366                        }
16367                    }
16368                    app.pendingUiClean = false;
16369                }
16370                app.trimMemoryLevel = 0;
16371            }
16372        }
16373
16374        if (mAlwaysFinishActivities) {
16375            // Need to do this on its own message because the stack may not
16376            // be in a consistent state at this point.
16377            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16378        }
16379
16380        if (allChanged) {
16381            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16382        }
16383
16384        if (mProcessStats.shouldWriteNowLocked(now)) {
16385            mHandler.post(new Runnable() {
16386                @Override public void run() {
16387                    synchronized (ActivityManagerService.this) {
16388                        mProcessStats.writeStateAsyncLocked();
16389                    }
16390                }
16391            });
16392        }
16393
16394        if (DEBUG_OOM_ADJ) {
16395            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16396        }
16397    }
16398
16399    final void trimApplications() {
16400        synchronized (this) {
16401            int i;
16402
16403            // First remove any unused application processes whose package
16404            // has been removed.
16405            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16406                final ProcessRecord app = mRemovedProcesses.get(i);
16407                if (app.activities.size() == 0
16408                        && app.curReceiver == null && app.services.size() == 0) {
16409                    Slog.i(
16410                        TAG, "Exiting empty application process "
16411                        + app.processName + " ("
16412                        + (app.thread != null ? app.thread.asBinder() : null)
16413                        + ")\n");
16414                    if (app.pid > 0 && app.pid != MY_PID) {
16415                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16416                                app.processName, app.setAdj, "empty");
16417                        app.killedByAm = true;
16418                        Process.killProcessQuiet(app.pid);
16419                    } else {
16420                        try {
16421                            app.thread.scheduleExit();
16422                        } catch (Exception e) {
16423                            // Ignore exceptions.
16424                        }
16425                    }
16426                    cleanUpApplicationRecordLocked(app, false, true, -1);
16427                    mRemovedProcesses.remove(i);
16428
16429                    if (app.persistent) {
16430                        if (app.persistent) {
16431                            addAppLocked(app.info, false, null /* ABI override */);
16432                        }
16433                    }
16434                }
16435            }
16436
16437            // Now update the oom adj for all processes.
16438            updateOomAdjLocked();
16439        }
16440    }
16441
16442    /** This method sends the specified signal to each of the persistent apps */
16443    public void signalPersistentProcesses(int sig) throws RemoteException {
16444        if (sig != Process.SIGNAL_USR1) {
16445            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16446        }
16447
16448        synchronized (this) {
16449            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16450                    != PackageManager.PERMISSION_GRANTED) {
16451                throw new SecurityException("Requires permission "
16452                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16453            }
16454
16455            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16456                ProcessRecord r = mLruProcesses.get(i);
16457                if (r.thread != null && r.persistent) {
16458                    Process.sendSignal(r.pid, sig);
16459                }
16460            }
16461        }
16462    }
16463
16464    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16465        if (proc == null || proc == mProfileProc) {
16466            proc = mProfileProc;
16467            path = mProfileFile;
16468            profileType = mProfileType;
16469            clearProfilerLocked();
16470        }
16471        if (proc == null) {
16472            return;
16473        }
16474        try {
16475            proc.thread.profilerControl(false, path, null, profileType);
16476        } catch (RemoteException e) {
16477            throw new IllegalStateException("Process disappeared");
16478        }
16479    }
16480
16481    private void clearProfilerLocked() {
16482        if (mProfileFd != null) {
16483            try {
16484                mProfileFd.close();
16485            } catch (IOException e) {
16486            }
16487        }
16488        mProfileApp = null;
16489        mProfileProc = null;
16490        mProfileFile = null;
16491        mProfileType = 0;
16492        mAutoStopProfiler = false;
16493    }
16494
16495    public boolean profileControl(String process, int userId, boolean start,
16496            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16497
16498        try {
16499            synchronized (this) {
16500                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16501                // its own permission.
16502                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16503                        != PackageManager.PERMISSION_GRANTED) {
16504                    throw new SecurityException("Requires permission "
16505                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16506                }
16507
16508                if (start && fd == null) {
16509                    throw new IllegalArgumentException("null fd");
16510                }
16511
16512                ProcessRecord proc = null;
16513                if (process != null) {
16514                    proc = findProcessLocked(process, userId, "profileControl");
16515                }
16516
16517                if (start && (proc == null || proc.thread == null)) {
16518                    throw new IllegalArgumentException("Unknown process: " + process);
16519                }
16520
16521                if (start) {
16522                    stopProfilerLocked(null, null, 0);
16523                    setProfileApp(proc.info, proc.processName, path, fd, false);
16524                    mProfileProc = proc;
16525                    mProfileType = profileType;
16526                    try {
16527                        fd = fd.dup();
16528                    } catch (IOException e) {
16529                        fd = null;
16530                    }
16531                    proc.thread.profilerControl(start, path, fd, profileType);
16532                    fd = null;
16533                    mProfileFd = null;
16534                } else {
16535                    stopProfilerLocked(proc, path, profileType);
16536                    if (fd != null) {
16537                        try {
16538                            fd.close();
16539                        } catch (IOException e) {
16540                        }
16541                    }
16542                }
16543
16544                return true;
16545            }
16546        } catch (RemoteException e) {
16547            throw new IllegalStateException("Process disappeared");
16548        } finally {
16549            if (fd != null) {
16550                try {
16551                    fd.close();
16552                } catch (IOException e) {
16553                }
16554            }
16555        }
16556    }
16557
16558    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16559        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16560                userId, true, true, callName, null);
16561        ProcessRecord proc = null;
16562        try {
16563            int pid = Integer.parseInt(process);
16564            synchronized (mPidsSelfLocked) {
16565                proc = mPidsSelfLocked.get(pid);
16566            }
16567        } catch (NumberFormatException e) {
16568        }
16569
16570        if (proc == null) {
16571            ArrayMap<String, SparseArray<ProcessRecord>> all
16572                    = mProcessNames.getMap();
16573            SparseArray<ProcessRecord> procs = all.get(process);
16574            if (procs != null && procs.size() > 0) {
16575                proc = procs.valueAt(0);
16576                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16577                    for (int i=1; i<procs.size(); i++) {
16578                        ProcessRecord thisProc = procs.valueAt(i);
16579                        if (thisProc.userId == userId) {
16580                            proc = thisProc;
16581                            break;
16582                        }
16583                    }
16584                }
16585            }
16586        }
16587
16588        return proc;
16589    }
16590
16591    public boolean dumpHeap(String process, int userId, boolean managed,
16592            String path, ParcelFileDescriptor fd) throws RemoteException {
16593
16594        try {
16595            synchronized (this) {
16596                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16597                // its own permission (same as profileControl).
16598                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16599                        != PackageManager.PERMISSION_GRANTED) {
16600                    throw new SecurityException("Requires permission "
16601                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16602                }
16603
16604                if (fd == null) {
16605                    throw new IllegalArgumentException("null fd");
16606                }
16607
16608                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16609                if (proc == null || proc.thread == null) {
16610                    throw new IllegalArgumentException("Unknown process: " + process);
16611                }
16612
16613                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16614                if (!isDebuggable) {
16615                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16616                        throw new SecurityException("Process not debuggable: " + proc);
16617                    }
16618                }
16619
16620                proc.thread.dumpHeap(managed, path, fd);
16621                fd = null;
16622                return true;
16623            }
16624        } catch (RemoteException e) {
16625            throw new IllegalStateException("Process disappeared");
16626        } finally {
16627            if (fd != null) {
16628                try {
16629                    fd.close();
16630                } catch (IOException e) {
16631                }
16632            }
16633        }
16634    }
16635
16636    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16637    public void monitor() {
16638        synchronized (this) { }
16639    }
16640
16641    void onCoreSettingsChange(Bundle settings) {
16642        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16643            ProcessRecord processRecord = mLruProcesses.get(i);
16644            try {
16645                if (processRecord.thread != null) {
16646                    processRecord.thread.setCoreSettings(settings);
16647                }
16648            } catch (RemoteException re) {
16649                /* ignore */
16650            }
16651        }
16652    }
16653
16654    // Multi-user methods
16655
16656    /**
16657     * Start user, if its not already running, but don't bring it to foreground.
16658     */
16659    @Override
16660    public boolean startUserInBackground(final int userId) {
16661        return startUser(userId, /* foreground */ false);
16662    }
16663
16664    /**
16665     * Refreshes the list of users related to the current user when either a
16666     * user switch happens or when a new related user is started in the
16667     * background.
16668     */
16669    private void updateCurrentProfileIdsLocked() {
16670        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16671                mCurrentUserId, false /* enabledOnly */);
16672        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16673        for (int i = 0; i < currentProfileIds.length; i++) {
16674            currentProfileIds[i] = profiles.get(i).id;
16675        }
16676        mCurrentProfileIds = currentProfileIds;
16677    }
16678
16679    private Set getProfileIdsLocked(int userId) {
16680        Set userIds = new HashSet<Integer>();
16681        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16682                userId, false /* enabledOnly */);
16683        for (UserInfo user : profiles) {
16684            userIds.add(Integer.valueOf(user.id));
16685        }
16686        return userIds;
16687    }
16688
16689    @Override
16690    public boolean switchUser(final int userId) {
16691        return startUser(userId, /* foregound */ true);
16692    }
16693
16694    private boolean startUser(final int userId, boolean foreground) {
16695        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16696                != PackageManager.PERMISSION_GRANTED) {
16697            String msg = "Permission Denial: switchUser() from pid="
16698                    + Binder.getCallingPid()
16699                    + ", uid=" + Binder.getCallingUid()
16700                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16701            Slog.w(TAG, msg);
16702            throw new SecurityException(msg);
16703        }
16704
16705        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16706
16707        final long ident = Binder.clearCallingIdentity();
16708        try {
16709            synchronized (this) {
16710                final int oldUserId = mCurrentUserId;
16711                if (oldUserId == userId) {
16712                    return true;
16713                }
16714
16715                mStackSupervisor.setLockTaskModeLocked(null);
16716
16717                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16718                if (userInfo == null) {
16719                    Slog.w(TAG, "No user info for user #" + userId);
16720                    return false;
16721                }
16722
16723                if (foreground) {
16724                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16725                            R.anim.screen_user_enter);
16726                }
16727
16728                boolean needStart = false;
16729
16730                // If the user we are switching to is not currently started, then
16731                // we need to start it now.
16732                if (mStartedUsers.get(userId) == null) {
16733                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16734                    updateStartedUserArrayLocked();
16735                    needStart = true;
16736                }
16737
16738                final Integer userIdInt = Integer.valueOf(userId);
16739                mUserLru.remove(userIdInt);
16740                mUserLru.add(userIdInt);
16741
16742                if (foreground) {
16743                    mCurrentUserId = userId;
16744                    updateCurrentProfileIdsLocked();
16745                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16746                    // Once the internal notion of the active user has switched, we lock the device
16747                    // with the option to show the user switcher on the keyguard.
16748                    mWindowManager.lockNow(null);
16749                } else {
16750                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16751                    updateCurrentProfileIdsLocked();
16752                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16753                    mUserLru.remove(currentUserIdInt);
16754                    mUserLru.add(currentUserIdInt);
16755                }
16756
16757                final UserStartedState uss = mStartedUsers.get(userId);
16758
16759                // Make sure user is in the started state.  If it is currently
16760                // stopping, we need to knock that off.
16761                if (uss.mState == UserStartedState.STATE_STOPPING) {
16762                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16763                    // so we can just fairly silently bring the user back from
16764                    // the almost-dead.
16765                    uss.mState = UserStartedState.STATE_RUNNING;
16766                    updateStartedUserArrayLocked();
16767                    needStart = true;
16768                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16769                    // This means ACTION_SHUTDOWN has been sent, so we will
16770                    // need to treat this as a new boot of the user.
16771                    uss.mState = UserStartedState.STATE_BOOTING;
16772                    updateStartedUserArrayLocked();
16773                    needStart = true;
16774                }
16775
16776                if (uss.mState == UserStartedState.STATE_BOOTING) {
16777                    // Booting up a new user, need to tell system services about it.
16778                    // Note that this is on the same handler as scheduling of broadcasts,
16779                    // which is important because it needs to go first.
16780                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16781                }
16782
16783                if (foreground) {
16784                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16785                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16786                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16787                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16788                            oldUserId, userId, uss));
16789                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16790                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16791                }
16792
16793                if (needStart) {
16794                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16795                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16796                            | Intent.FLAG_RECEIVER_FOREGROUND);
16797                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16798                    broadcastIntentLocked(null, null, intent,
16799                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16800                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16801                }
16802
16803                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16804                    if (userId != UserHandle.USER_OWNER) {
16805                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16806                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16807                        broadcastIntentLocked(null, null, intent, null,
16808                                new IIntentReceiver.Stub() {
16809                                    public void performReceive(Intent intent, int resultCode,
16810                                            String data, Bundle extras, boolean ordered,
16811                                            boolean sticky, int sendingUser) {
16812                                        userInitialized(uss, userId);
16813                                    }
16814                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16815                                true, false, MY_PID, Process.SYSTEM_UID,
16816                                userId);
16817                        uss.initializing = true;
16818                    } else {
16819                        getUserManagerLocked().makeInitialized(userInfo.id);
16820                    }
16821                }
16822
16823                if (foreground) {
16824                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16825                    if (homeInFront) {
16826                        startHomeActivityLocked(userId);
16827                    } else {
16828                        mStackSupervisor.resumeTopActivitiesLocked();
16829                    }
16830                    EventLogTags.writeAmSwitchUser(userId);
16831                    getUserManagerLocked().userForeground(userId);
16832                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16833                } else {
16834                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16835                }
16836
16837                if (needStart) {
16838                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16839                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16840                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16841                    broadcastIntentLocked(null, null, intent,
16842                            null, new IIntentReceiver.Stub() {
16843                                @Override
16844                                public void performReceive(Intent intent, int resultCode, String data,
16845                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16846                                        throws RemoteException {
16847                                }
16848                            }, 0, null, null,
16849                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16850                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16851                }
16852            }
16853        } finally {
16854            Binder.restoreCallingIdentity(ident);
16855        }
16856
16857        return true;
16858    }
16859
16860    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16861        long ident = Binder.clearCallingIdentity();
16862        try {
16863            Intent intent;
16864            if (oldUserId >= 0) {
16865                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16866                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16867                        | Intent.FLAG_RECEIVER_FOREGROUND);
16868                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16869                broadcastIntentLocked(null, null, intent,
16870                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16871                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16872            }
16873            if (newUserId >= 0) {
16874                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16875                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16876                        | Intent.FLAG_RECEIVER_FOREGROUND);
16877                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16878                broadcastIntentLocked(null, null, intent,
16879                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16880                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16881                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16882                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16883                        | Intent.FLAG_RECEIVER_FOREGROUND);
16884                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16885                broadcastIntentLocked(null, null, intent,
16886                        null, null, 0, null, null,
16887                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16888                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16889            }
16890        } finally {
16891            Binder.restoreCallingIdentity(ident);
16892        }
16893    }
16894
16895    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16896            final int newUserId) {
16897        final int N = mUserSwitchObservers.beginBroadcast();
16898        if (N > 0) {
16899            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16900                int mCount = 0;
16901                @Override
16902                public void sendResult(Bundle data) throws RemoteException {
16903                    synchronized (ActivityManagerService.this) {
16904                        if (mCurUserSwitchCallback == this) {
16905                            mCount++;
16906                            if (mCount == N) {
16907                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16908                            }
16909                        }
16910                    }
16911                }
16912            };
16913            synchronized (this) {
16914                uss.switching = true;
16915                mCurUserSwitchCallback = callback;
16916            }
16917            for (int i=0; i<N; i++) {
16918                try {
16919                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16920                            newUserId, callback);
16921                } catch (RemoteException e) {
16922                }
16923            }
16924        } else {
16925            synchronized (this) {
16926                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16927            }
16928        }
16929        mUserSwitchObservers.finishBroadcast();
16930    }
16931
16932    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16933        synchronized (this) {
16934            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16935            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16936        }
16937    }
16938
16939    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16940        mCurUserSwitchCallback = null;
16941        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16942        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16943                oldUserId, newUserId, uss));
16944    }
16945
16946    void userInitialized(UserStartedState uss, int newUserId) {
16947        completeSwitchAndInitalize(uss, newUserId, true, false);
16948    }
16949
16950    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16951        completeSwitchAndInitalize(uss, newUserId, false, true);
16952    }
16953
16954    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16955            boolean clearInitializing, boolean clearSwitching) {
16956        boolean unfrozen = false;
16957        synchronized (this) {
16958            if (clearInitializing) {
16959                uss.initializing = false;
16960                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16961            }
16962            if (clearSwitching) {
16963                uss.switching = false;
16964            }
16965            if (!uss.switching && !uss.initializing) {
16966                mWindowManager.stopFreezingScreen();
16967                unfrozen = true;
16968            }
16969        }
16970        if (unfrozen) {
16971            final int N = mUserSwitchObservers.beginBroadcast();
16972            for (int i=0; i<N; i++) {
16973                try {
16974                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16975                } catch (RemoteException e) {
16976                }
16977            }
16978            mUserSwitchObservers.finishBroadcast();
16979        }
16980    }
16981
16982    void scheduleStartProfilesLocked() {
16983        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16984            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16985                    DateUtils.SECOND_IN_MILLIS);
16986        }
16987    }
16988
16989    void startProfilesLocked() {
16990        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16991        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16992                mCurrentUserId, false /* enabledOnly */);
16993        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16994        for (UserInfo user : profiles) {
16995            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16996                    && user.id != mCurrentUserId) {
16997                toStart.add(user);
16998            }
16999        }
17000        final int n = toStart.size();
17001        int i = 0;
17002        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17003            startUserInBackground(toStart.get(i).id);
17004        }
17005        if (i < n) {
17006            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17007        }
17008    }
17009
17010    void finishUserBoot(UserStartedState uss) {
17011        synchronized (this) {
17012            if (uss.mState == UserStartedState.STATE_BOOTING
17013                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17014                uss.mState = UserStartedState.STATE_RUNNING;
17015                final int userId = uss.mHandle.getIdentifier();
17016                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17017                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17018                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17019                broadcastIntentLocked(null, null, intent,
17020                        null, null, 0, null, null,
17021                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17022                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17023            }
17024        }
17025    }
17026
17027    void finishUserSwitch(UserStartedState uss) {
17028        synchronized (this) {
17029            finishUserBoot(uss);
17030
17031            startProfilesLocked();
17032
17033            int num = mUserLru.size();
17034            int i = 0;
17035            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17036                Integer oldUserId = mUserLru.get(i);
17037                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17038                if (oldUss == null) {
17039                    // Shouldn't happen, but be sane if it does.
17040                    mUserLru.remove(i);
17041                    num--;
17042                    continue;
17043                }
17044                if (oldUss.mState == UserStartedState.STATE_STOPPING
17045                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17046                    // This user is already stopping, doesn't count.
17047                    num--;
17048                    i++;
17049                    continue;
17050                }
17051                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17052                    // Owner and current can't be stopped, but count as running.
17053                    i++;
17054                    continue;
17055                }
17056                // This is a user to be stopped.
17057                stopUserLocked(oldUserId, null);
17058                num--;
17059                i++;
17060            }
17061        }
17062    }
17063
17064    @Override
17065    public int stopUser(final int userId, final IStopUserCallback callback) {
17066        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17067                != PackageManager.PERMISSION_GRANTED) {
17068            String msg = "Permission Denial: switchUser() from pid="
17069                    + Binder.getCallingPid()
17070                    + ", uid=" + Binder.getCallingUid()
17071                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17072            Slog.w(TAG, msg);
17073            throw new SecurityException(msg);
17074        }
17075        if (userId <= 0) {
17076            throw new IllegalArgumentException("Can't stop primary user " + userId);
17077        }
17078        synchronized (this) {
17079            return stopUserLocked(userId, callback);
17080        }
17081    }
17082
17083    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17084        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17085        if (mCurrentUserId == userId) {
17086            return ActivityManager.USER_OP_IS_CURRENT;
17087        }
17088
17089        final UserStartedState uss = mStartedUsers.get(userId);
17090        if (uss == null) {
17091            // User is not started, nothing to do...  but we do need to
17092            // callback if requested.
17093            if (callback != null) {
17094                mHandler.post(new Runnable() {
17095                    @Override
17096                    public void run() {
17097                        try {
17098                            callback.userStopped(userId);
17099                        } catch (RemoteException e) {
17100                        }
17101                    }
17102                });
17103            }
17104            return ActivityManager.USER_OP_SUCCESS;
17105        }
17106
17107        if (callback != null) {
17108            uss.mStopCallbacks.add(callback);
17109        }
17110
17111        if (uss.mState != UserStartedState.STATE_STOPPING
17112                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17113            uss.mState = UserStartedState.STATE_STOPPING;
17114            updateStartedUserArrayLocked();
17115
17116            long ident = Binder.clearCallingIdentity();
17117            try {
17118                // We are going to broadcast ACTION_USER_STOPPING and then
17119                // once that is done send a final ACTION_SHUTDOWN and then
17120                // stop the user.
17121                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17122                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17123                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17124                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17125                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17126                // This is the result receiver for the final shutdown broadcast.
17127                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17128                    @Override
17129                    public void performReceive(Intent intent, int resultCode, String data,
17130                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17131                        finishUserStop(uss);
17132                    }
17133                };
17134                // This is the result receiver for the initial stopping broadcast.
17135                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17136                    @Override
17137                    public void performReceive(Intent intent, int resultCode, String data,
17138                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17139                        // On to the next.
17140                        synchronized (ActivityManagerService.this) {
17141                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17142                                // Whoops, we are being started back up.  Abort, abort!
17143                                return;
17144                            }
17145                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17146                        }
17147                        mSystemServiceManager.stopUser(userId);
17148                        broadcastIntentLocked(null, null, shutdownIntent,
17149                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17150                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17151                    }
17152                };
17153                // Kick things off.
17154                broadcastIntentLocked(null, null, stoppingIntent,
17155                        null, stoppingReceiver, 0, null, null,
17156                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17157                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17158            } finally {
17159                Binder.restoreCallingIdentity(ident);
17160            }
17161        }
17162
17163        return ActivityManager.USER_OP_SUCCESS;
17164    }
17165
17166    void finishUserStop(UserStartedState uss) {
17167        final int userId = uss.mHandle.getIdentifier();
17168        boolean stopped;
17169        ArrayList<IStopUserCallback> callbacks;
17170        synchronized (this) {
17171            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17172            if (mStartedUsers.get(userId) != uss) {
17173                stopped = false;
17174            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17175                stopped = false;
17176            } else {
17177                stopped = true;
17178                // User can no longer run.
17179                mStartedUsers.remove(userId);
17180                mUserLru.remove(Integer.valueOf(userId));
17181                updateStartedUserArrayLocked();
17182
17183                // Clean up all state and processes associated with the user.
17184                // Kill all the processes for the user.
17185                forceStopUserLocked(userId, "finish user");
17186            }
17187        }
17188
17189        for (int i=0; i<callbacks.size(); i++) {
17190            try {
17191                if (stopped) callbacks.get(i).userStopped(userId);
17192                else callbacks.get(i).userStopAborted(userId);
17193            } catch (RemoteException e) {
17194            }
17195        }
17196
17197        if (stopped) {
17198            mSystemServiceManager.cleanupUser(userId);
17199            synchronized (this) {
17200                mStackSupervisor.removeUserLocked(userId);
17201            }
17202        }
17203    }
17204
17205    @Override
17206    public UserInfo getCurrentUser() {
17207        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17208                != PackageManager.PERMISSION_GRANTED) && (
17209                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17210                != PackageManager.PERMISSION_GRANTED)) {
17211            String msg = "Permission Denial: getCurrentUser() from pid="
17212                    + Binder.getCallingPid()
17213                    + ", uid=" + Binder.getCallingUid()
17214                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17215            Slog.w(TAG, msg);
17216            throw new SecurityException(msg);
17217        }
17218        synchronized (this) {
17219            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17220        }
17221    }
17222
17223    int getCurrentUserIdLocked() {
17224        return mCurrentUserId;
17225    }
17226
17227    @Override
17228    public boolean isUserRunning(int userId, boolean orStopped) {
17229        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17230                != PackageManager.PERMISSION_GRANTED) {
17231            String msg = "Permission Denial: isUserRunning() from pid="
17232                    + Binder.getCallingPid()
17233                    + ", uid=" + Binder.getCallingUid()
17234                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17235            Slog.w(TAG, msg);
17236            throw new SecurityException(msg);
17237        }
17238        synchronized (this) {
17239            return isUserRunningLocked(userId, orStopped);
17240        }
17241    }
17242
17243    boolean isUserRunningLocked(int userId, boolean orStopped) {
17244        UserStartedState state = mStartedUsers.get(userId);
17245        if (state == null) {
17246            return false;
17247        }
17248        if (orStopped) {
17249            return true;
17250        }
17251        return state.mState != UserStartedState.STATE_STOPPING
17252                && state.mState != UserStartedState.STATE_SHUTDOWN;
17253    }
17254
17255    @Override
17256    public int[] getRunningUserIds() {
17257        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17258                != PackageManager.PERMISSION_GRANTED) {
17259            String msg = "Permission Denial: isUserRunning() from pid="
17260                    + Binder.getCallingPid()
17261                    + ", uid=" + Binder.getCallingUid()
17262                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17263            Slog.w(TAG, msg);
17264            throw new SecurityException(msg);
17265        }
17266        synchronized (this) {
17267            return mStartedUserArray;
17268        }
17269    }
17270
17271    private void updateStartedUserArrayLocked() {
17272        int num = 0;
17273        for (int i=0; i<mStartedUsers.size();  i++) {
17274            UserStartedState uss = mStartedUsers.valueAt(i);
17275            // This list does not include stopping users.
17276            if (uss.mState != UserStartedState.STATE_STOPPING
17277                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17278                num++;
17279            }
17280        }
17281        mStartedUserArray = new int[num];
17282        num = 0;
17283        for (int i=0; i<mStartedUsers.size();  i++) {
17284            UserStartedState uss = mStartedUsers.valueAt(i);
17285            if (uss.mState != UserStartedState.STATE_STOPPING
17286                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17287                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17288                num++;
17289            }
17290        }
17291    }
17292
17293    @Override
17294    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17295        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17296                != PackageManager.PERMISSION_GRANTED) {
17297            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17298                    + Binder.getCallingPid()
17299                    + ", uid=" + Binder.getCallingUid()
17300                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17301            Slog.w(TAG, msg);
17302            throw new SecurityException(msg);
17303        }
17304
17305        mUserSwitchObservers.register(observer);
17306    }
17307
17308    @Override
17309    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17310        mUserSwitchObservers.unregister(observer);
17311    }
17312
17313    private boolean userExists(int userId) {
17314        if (userId == 0) {
17315            return true;
17316        }
17317        UserManagerService ums = getUserManagerLocked();
17318        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17319    }
17320
17321    int[] getUsersLocked() {
17322        UserManagerService ums = getUserManagerLocked();
17323        return ums != null ? ums.getUserIds() : new int[] { 0 };
17324    }
17325
17326    UserManagerService getUserManagerLocked() {
17327        if (mUserManager == null) {
17328            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17329            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17330        }
17331        return mUserManager;
17332    }
17333
17334    private int applyUserId(int uid, int userId) {
17335        return UserHandle.getUid(userId, uid);
17336    }
17337
17338    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17339        if (info == null) return null;
17340        ApplicationInfo newInfo = new ApplicationInfo(info);
17341        newInfo.uid = applyUserId(info.uid, userId);
17342        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17343                + info.packageName;
17344        return newInfo;
17345    }
17346
17347    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17348        if (aInfo == null
17349                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17350            return aInfo;
17351        }
17352
17353        ActivityInfo info = new ActivityInfo(aInfo);
17354        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17355        return info;
17356    }
17357
17358    private final class LocalService extends ActivityManagerInternal {
17359        @Override
17360        public void goingToSleep() {
17361            ActivityManagerService.this.goingToSleep();
17362        }
17363
17364        @Override
17365        public void wakingUp() {
17366            ActivityManagerService.this.wakingUp();
17367        }
17368    }
17369
17370    /**
17371     * An implementation of IAppTask, that allows an app to manage its own tasks via
17372     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17373     * only the process that calls getAppTasks() can call the AppTask methods.
17374     */
17375    class AppTaskImpl extends IAppTask.Stub {
17376        private int mTaskId;
17377        private int mCallingUid;
17378
17379        public AppTaskImpl(int taskId, int callingUid) {
17380            mTaskId = taskId;
17381            mCallingUid = callingUid;
17382        }
17383
17384        @Override
17385        public void finishAndRemoveTask() {
17386            // Ensure that we are called from the same process that created this AppTask
17387            if (mCallingUid != Binder.getCallingUid()) {
17388                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17389                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17390                return;
17391            }
17392
17393            synchronized (ActivityManagerService.this) {
17394                long origId = Binder.clearCallingIdentity();
17395                try {
17396                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17397                    if (tr != null) {
17398                        // Only kill the process if we are not a new document
17399                        int flags = tr.getBaseIntent().getFlags();
17400                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17401                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17402                        removeTaskByIdLocked(mTaskId,
17403                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17404                    }
17405                } finally {
17406                    Binder.restoreCallingIdentity(origId);
17407                }
17408            }
17409        }
17410
17411        @Override
17412        public ActivityManager.RecentTaskInfo getTaskInfo() {
17413            // Ensure that we are called from the same process that created this AppTask
17414            if (mCallingUid != Binder.getCallingUid()) {
17415                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17416                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17417                return null;
17418            }
17419
17420            synchronized (ActivityManagerService.this) {
17421                long origId = Binder.clearCallingIdentity();
17422                try {
17423                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17424                    if (tr != null) {
17425                        return createRecentTaskInfoFromTaskRecord(tr);
17426                    }
17427                } finally {
17428                    Binder.restoreCallingIdentity(origId);
17429                }
17430                return null;
17431            }
17432        }
17433    }
17434}
17435