ActivityManagerService.java revision 099bc627c463d9941e23e480f25a78a154429c55
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.os.BatteryStats;
36import android.util.ArrayMap;
37import com.android.internal.R;
38import com.android.internal.annotations.GuardedBy;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.app.ProcessMap;
41import com.android.internal.app.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.ServiceThread;
54import com.android.server.SystemServer;
55import com.android.server.SystemService;
56import com.android.server.Watchdog;
57import com.android.server.am.ActivityStack.ActivityState;
58import com.android.server.firewall.IntentFirewall;
59import com.android.server.pm.UserManagerService;
60import com.android.server.wm.AppTransition;
61import com.android.server.wm.WindowManagerService;
62import com.google.android.collect.Lists;
63import com.google.android.collect.Maps;
64
65import dalvik.system.Zygote;
66
67import libcore.io.IoUtils;
68
69import org.xmlpull.v1.XmlPullParser;
70import org.xmlpull.v1.XmlPullParserException;
71import org.xmlpull.v1.XmlSerializer;
72
73import android.app.Activity;
74import android.app.ActivityManager;
75import android.app.ActivityManager.RunningTaskInfo;
76import android.app.ActivityManager.StackInfo;
77import android.app.ActivityManagerNative;
78import android.app.ActivityOptions;
79import android.app.ActivityThread;
80import android.app.AlertDialog;
81import android.app.AppGlobals;
82import android.app.ApplicationErrorReport;
83import android.app.Dialog;
84import android.app.IActivityController;
85import android.app.IApplicationThread;
86import android.app.IInstrumentationWatcher;
87import android.app.INotificationManager;
88import android.app.IProcessObserver;
89import android.app.IServiceConnection;
90import android.app.IStopUserCallback;
91import android.app.IThumbnailReceiver;
92import android.app.IUiAutomationConnection;
93import android.app.IUserSwitchObserver;
94import android.app.Instrumentation;
95import android.app.Notification;
96import android.app.NotificationManager;
97import android.app.PendingIntent;
98import android.app.backup.IBackupManager;
99import android.content.ActivityNotFoundException;
100import android.content.BroadcastReceiver;
101import android.content.ClipData;
102import android.content.ComponentCallbacks2;
103import android.content.ComponentName;
104import android.content.ContentProvider;
105import android.content.ContentResolver;
106import android.content.Context;
107import android.content.DialogInterface;
108import android.content.IContentProvider;
109import android.content.IIntentReceiver;
110import android.content.IIntentSender;
111import android.content.Intent;
112import android.content.IntentFilter;
113import android.content.IntentSender;
114import android.content.pm.ActivityInfo;
115import android.content.pm.ApplicationInfo;
116import android.content.pm.ConfigurationInfo;
117import android.content.pm.IPackageDataObserver;
118import android.content.pm.IPackageManager;
119import android.content.pm.InstrumentationInfo;
120import android.content.pm.PackageInfo;
121import android.content.pm.PackageManager;
122import android.content.pm.ParceledListSlice;
123import android.content.pm.UserInfo;
124import android.content.pm.PackageManager.NameNotFoundException;
125import android.content.pm.PathPermission;
126import android.content.pm.ProviderInfo;
127import android.content.pm.ResolveInfo;
128import android.content.pm.ServiceInfo;
129import android.content.res.CompatibilityInfo;
130import android.content.res.Configuration;
131import android.graphics.Bitmap;
132import android.net.Proxy;
133import android.net.ProxyProperties;
134import android.net.Uri;
135import android.os.Binder;
136import android.os.Build;
137import android.os.Bundle;
138import android.os.Debug;
139import android.os.DropBoxManager;
140import android.os.Environment;
141import android.os.FactoryTest;
142import android.os.FileObserver;
143import android.os.FileUtils;
144import android.os.Handler;
145import android.os.IBinder;
146import android.os.IPermissionController;
147import android.os.IRemoteCallback;
148import android.os.IUserManager;
149import android.os.Looper;
150import android.os.Message;
151import android.os.Parcel;
152import android.os.ParcelFileDescriptor;
153import android.os.Process;
154import android.os.RemoteCallbackList;
155import android.os.RemoteException;
156import android.os.SELinux;
157import android.os.ServiceManager;
158import android.os.StrictMode;
159import android.os.SystemClock;
160import android.os.SystemProperties;
161import android.os.UpdateLock;
162import android.os.UserHandle;
163import android.provider.Settings;
164import android.text.format.DateUtils;
165import android.text.format.Time;
166import android.util.AtomicFile;
167import android.util.EventLog;
168import android.util.Log;
169import android.util.Pair;
170import android.util.PrintWriterPrinter;
171import android.util.Slog;
172import android.util.SparseArray;
173import android.util.TimeUtils;
174import android.util.Xml;
175import android.view.Gravity;
176import android.view.LayoutInflater;
177import android.view.View;
178import android.view.WindowManager;
179
180import java.io.BufferedInputStream;
181import java.io.BufferedOutputStream;
182import java.io.DataInputStream;
183import java.io.DataOutputStream;
184import java.io.File;
185import java.io.FileDescriptor;
186import java.io.FileInputStream;
187import java.io.FileNotFoundException;
188import java.io.FileOutputStream;
189import java.io.IOException;
190import java.io.InputStreamReader;
191import java.io.PrintWriter;
192import java.io.StringWriter;
193import java.lang.ref.WeakReference;
194import java.util.ArrayList;
195import java.util.Arrays;
196import java.util.Collections;
197import java.util.Comparator;
198import java.util.HashMap;
199import java.util.HashSet;
200import java.util.Iterator;
201import java.util.List;
202import java.util.Locale;
203import java.util.Map;
204import java.util.Set;
205import java.util.concurrent.atomic.AtomicBoolean;
206import java.util.concurrent.atomic.AtomicLong;
207
208public final class ActivityManagerService extends ActivityManagerNative
209        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
210    private static final String USER_DATA_DIR = "/data/user/";
211    static final String TAG = "ActivityManager";
212    static final String TAG_MU = "ActivityManagerServiceMU";
213    static final boolean DEBUG = false;
214    static final boolean localLOGV = DEBUG;
215    static final boolean DEBUG_BACKUP = localLOGV || false;
216    static final boolean DEBUG_BROADCAST = localLOGV || false;
217    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
219    static final boolean DEBUG_CLEANUP = localLOGV || false;
220    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
221    static final boolean DEBUG_FOCUS = false;
222    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
223    static final boolean DEBUG_MU = localLOGV || false;
224    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
225    static final boolean DEBUG_LRU = localLOGV || false;
226    static final boolean DEBUG_PAUSE = localLOGV || false;
227    static final boolean DEBUG_POWER = localLOGV || false;
228    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
229    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
230    static final boolean DEBUG_PROCESSES = localLOGV || false;
231    static final boolean DEBUG_PROVIDER = localLOGV || false;
232    static final boolean DEBUG_RESULTS = localLOGV || false;
233    static final boolean DEBUG_SERVICE = localLOGV || false;
234    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
235    static final boolean DEBUG_STACK = localLOGV || false;
236    static final boolean DEBUG_SWITCH = localLOGV || false;
237    static final boolean DEBUG_TASKS = localLOGV || false;
238    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
239    static final boolean DEBUG_TRANSITION = localLOGV || false;
240    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
241    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
242    static final boolean DEBUG_VISBILITY = localLOGV || false;
243    static final boolean DEBUG_PSS = localLOGV || false;
244    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
245    static final boolean VALIDATE_TOKENS = false;
246    static final boolean SHOW_ACTIVITY_START_TIME = true;
247
248    // Control over CPU and battery monitoring.
249    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
250    static final boolean MONITOR_CPU_USAGE = true;
251    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
252    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
253    static final boolean MONITOR_THREAD_CPU_USAGE = false;
254
255    // The flags that are set for all calls we make to the package manager.
256    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
257
258    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
259
260    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
261
262    // Maximum number of recent tasks that we can remember.
263    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
264
265    // Amount of time after a call to stopAppSwitches() during which we will
266    // prevent further untrusted switches from happening.
267    static final long APP_SWITCH_DELAY_TIME = 5*1000;
268
269    // How long we wait for a launched process to attach to the activity manager
270    // before we decide it's never going to come up for real.
271    static final int PROC_START_TIMEOUT = 10*1000;
272
273    // How long we wait for a launched process to attach to the activity manager
274    // before we decide it's never going to come up for real, when the process was
275    // started with a wrapper for instrumentation (such as Valgrind) because it
276    // could take much longer than usual.
277    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
278
279    // How long to wait after going idle before forcing apps to GC.
280    static final int GC_TIMEOUT = 5*1000;
281
282    // The minimum amount of time between successive GC requests for a process.
283    static final int GC_MIN_INTERVAL = 60*1000;
284
285    // The minimum amount of time between successive PSS requests for a process.
286    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
287
288    // The minimum amount of time between successive PSS requests for a process
289    // when the request is due to the memory state being lowered.
290    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
291
292    // The rate at which we check for apps using excessive power -- 15 mins.
293    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
294
295    // The minimum sample duration we will allow before deciding we have
296    // enough data on wake locks to start killing things.
297    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
298
299    // The minimum sample duration we will allow before deciding we have
300    // enough data on CPU usage to start killing things.
301    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
302
303    // How long we allow a receiver to run before giving up on it.
304    static final int BROADCAST_FG_TIMEOUT = 10*1000;
305    static final int BROADCAST_BG_TIMEOUT = 60*1000;
306
307    // How long we wait until we timeout on key dispatching.
308    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
309
310    // How long we wait until we timeout on key dispatching during instrumentation.
311    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
312
313    // Amount of time we wait for observers to handle a user switch before
314    // giving up on them and unfreezing the screen.
315    static final int USER_SWITCH_TIMEOUT = 2*1000;
316
317    // Maximum number of users we allow to be running at a time.
318    static final int MAX_RUNNING_USERS = 3;
319
320    // How long to wait in getAssistContextExtras for the activity and foreground services
321    // to respond with the result.
322    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
323
324    // Maximum number of persisted Uri grants a package is allowed
325    static final int MAX_PERSISTED_URI_GRANTS = 128;
326
327    static final int MY_PID = Process.myPid();
328
329    static final String[] EMPTY_STRING_ARRAY = new String[0];
330
331    // How many bytes to write into the dropbox log before truncating
332    static final int DROPBOX_MAX_SIZE = 256 * 1024;
333
334    /** Run all ActivityStacks through this */
335    ActivityStackSupervisor mStackSupervisor;
336
337    public IntentFirewall mIntentFirewall;
338
339    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
340    // default actuion automatically.  Important for devices without direct input
341    // devices.
342    private boolean mShowDialogs = true;
343
344    /**
345     * Description of a request to start a new activity, which has been held
346     * due to app switches being disabled.
347     */
348    static class PendingActivityLaunch {
349        final ActivityRecord r;
350        final ActivityRecord sourceRecord;
351        final int startFlags;
352        final ActivityStack stack;
353
354        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
355                int _startFlags, ActivityStack _stack) {
356            r = _r;
357            sourceRecord = _sourceRecord;
358            startFlags = _startFlags;
359            stack = _stack;
360        }
361    }
362
363    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
364            = new ArrayList<PendingActivityLaunch>();
365
366    BroadcastQueue mFgBroadcastQueue;
367    BroadcastQueue mBgBroadcastQueue;
368    // Convenient for easy iteration over the queues. Foreground is first
369    // so that dispatch of foreground broadcasts gets precedence.
370    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
371
372    BroadcastQueue broadcastQueueForIntent(Intent intent) {
373        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
374        if (DEBUG_BACKGROUND_BROADCAST) {
375            Slog.i(TAG, "Broadcast intent " + intent + " on "
376                    + (isFg ? "foreground" : "background")
377                    + " queue");
378        }
379        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
380    }
381
382    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
383        for (BroadcastQueue queue : mBroadcastQueues) {
384            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
385            if (r != null) {
386                return r;
387            }
388        }
389        return null;
390    }
391
392    /**
393     * Activity we have told the window manager to have key focus.
394     */
395    ActivityRecord mFocusedActivity = null;
396
397    /**
398     * List of intents that were used to start the most recent tasks.
399     */
400    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
401
402    public class PendingAssistExtras extends Binder implements Runnable {
403        public final ActivityRecord activity;
404        public boolean haveResult = false;
405        public Bundle result = null;
406        public PendingAssistExtras(ActivityRecord _activity) {
407            activity = _activity;
408        }
409        @Override
410        public void run() {
411            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
412            synchronized (this) {
413                haveResult = true;
414                notifyAll();
415            }
416        }
417    }
418
419    final ArrayList<PendingAssistExtras> mPendingAssistExtras
420            = new ArrayList<PendingAssistExtras>();
421
422    /**
423     * Process management.
424     */
425    final ProcessList mProcessList = new ProcessList();
426
427    /**
428     * All of the applications we currently have running organized by name.
429     * The keys are strings of the application package name (as
430     * returned by the package manager), and the keys are ApplicationRecord
431     * objects.
432     */
433    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
434
435    /**
436     * Tracking long-term execution of processes to look for abuse and other
437     * bad app behavior.
438     */
439    final ProcessStatsService mProcessStats;
440
441    /**
442     * The currently running isolated processes.
443     */
444    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
445
446    /**
447     * Counter for assigning isolated process uids, to avoid frequently reusing the
448     * same ones.
449     */
450    int mNextIsolatedProcessUid = 0;
451
452    /**
453     * The currently running heavy-weight process, if any.
454     */
455    ProcessRecord mHeavyWeightProcess = null;
456
457    /**
458     * The last time that various processes have crashed.
459     */
460    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
461
462    /**
463     * Information about a process that is currently marked as bad.
464     */
465    static final class BadProcessInfo {
466        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
467            this.time = time;
468            this.shortMsg = shortMsg;
469            this.longMsg = longMsg;
470            this.stack = stack;
471        }
472
473        final long time;
474        final String shortMsg;
475        final String longMsg;
476        final String stack;
477    }
478
479    /**
480     * Set of applications that we consider to be bad, and will reject
481     * incoming broadcasts from (which the user has no control over).
482     * Processes are added to this set when they have crashed twice within
483     * a minimum amount of time; they are removed from it when they are
484     * later restarted (hopefully due to some user action).  The value is the
485     * time it was added to the list.
486     */
487    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
488
489    /**
490     * All of the processes we currently have running organized by pid.
491     * The keys are the pid running the application.
492     *
493     * <p>NOTE: This object is protected by its own lock, NOT the global
494     * activity manager lock!
495     */
496    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
497
498    /**
499     * All of the processes that have been forced to be foreground.  The key
500     * is the pid of the caller who requested it (we hold a death
501     * link on it).
502     */
503    abstract class ForegroundToken implements IBinder.DeathRecipient {
504        int pid;
505        IBinder token;
506    }
507    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
508
509    /**
510     * List of records for processes that someone had tried to start before the
511     * system was ready.  We don't start them at that point, but ensure they
512     * are started by the time booting is complete.
513     */
514    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
515
516    /**
517     * List of persistent applications that are in the process
518     * of being started.
519     */
520    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
521
522    /**
523     * Processes that are being forcibly torn down.
524     */
525    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of running applications, sorted by recent usage.
529     * The first entry in the list is the least recently used.
530     */
531    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Where in mLruProcesses that the processes hosting activities start.
535     */
536    int mLruProcessActivityStart = 0;
537
538    /**
539     * Where in mLruProcesses that the processes hosting services start.
540     * This is after (lower index) than mLruProcessesActivityStart.
541     */
542    int mLruProcessServiceStart = 0;
543
544    /**
545     * List of processes that should gc as soon as things are idle.
546     */
547    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
548
549    /**
550     * Processes we want to collect PSS data from.
551     */
552    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
553
554    /**
555     * Last time we requested PSS data of all processes.
556     */
557    long mLastFullPssTime = SystemClock.uptimeMillis();
558
559    /**
560     * This is the process holding what we currently consider to be
561     * the "home" activity.
562     */
563    ProcessRecord mHomeProcess;
564
565    /**
566     * This is the process holding the activity the user last visited that
567     * is in a different process from the one they are currently in.
568     */
569    ProcessRecord mPreviousProcess;
570
571    /**
572     * The time at which the previous process was last visible.
573     */
574    long mPreviousProcessVisibleTime;
575
576    /**
577     * Which uses have been started, so are allowed to run code.
578     */
579    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
580
581    /**
582     * LRU list of history of current users.  Most recently current is at the end.
583     */
584    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
585
586    /**
587     * Constant array of the users that are currently started.
588     */
589    int[] mStartedUserArray = new int[] { 0 };
590
591    /**
592     * Registered observers of the user switching mechanics.
593     */
594    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
595            = new RemoteCallbackList<IUserSwitchObserver>();
596
597    /**
598     * Currently active user switch.
599     */
600    Object mCurUserSwitchCallback;
601
602    /**
603     * Packages that the user has asked to have run in screen size
604     * compatibility mode instead of filling the screen.
605     */
606    final CompatModePackages mCompatModePackages;
607
608    /**
609     * Set of IntentSenderRecord objects that are currently active.
610     */
611    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
612            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
613
614    /**
615     * Fingerprints (hashCode()) of stack traces that we've
616     * already logged DropBox entries for.  Guarded by itself.  If
617     * something (rogue user app) forces this over
618     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
619     */
620    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
621    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
622
623    /**
624     * Strict Mode background batched logging state.
625     *
626     * The string buffer is guarded by itself, and its lock is also
627     * used to determine if another batched write is already
628     * in-flight.
629     */
630    private final StringBuilder mStrictModeBuffer = new StringBuilder();
631
632    /**
633     * Keeps track of all IIntentReceivers that have been registered for
634     * broadcasts.  Hash keys are the receiver IBinder, hash value is
635     * a ReceiverList.
636     */
637    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
638            new HashMap<IBinder, ReceiverList>();
639
640    /**
641     * Resolver for broadcast intents to registered receivers.
642     * Holds BroadcastFilter (subclass of IntentFilter).
643     */
644    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
645            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
646        @Override
647        protected boolean allowFilterResult(
648                BroadcastFilter filter, List<BroadcastFilter> dest) {
649            IBinder target = filter.receiverList.receiver.asBinder();
650            for (int i=dest.size()-1; i>=0; i--) {
651                if (dest.get(i).receiverList.receiver.asBinder() == target) {
652                    return false;
653                }
654            }
655            return true;
656        }
657
658        @Override
659        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
660            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
661                    || userId == filter.owningUserId) {
662                return super.newResult(filter, match, userId);
663            }
664            return null;
665        }
666
667        @Override
668        protected BroadcastFilter[] newArray(int size) {
669            return new BroadcastFilter[size];
670        }
671
672        @Override
673        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
674            return packageName.equals(filter.packageName);
675        }
676    };
677
678    /**
679     * State of all active sticky broadcasts per user.  Keys are the action of the
680     * sticky Intent, values are an ArrayList of all broadcasted intents with
681     * that action (which should usually be one).  The SparseArray is keyed
682     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
683     * for stickies that are sent to all users.
684     */
685    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
686            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
687
688    final ActiveServices mServices;
689
690    /**
691     * Backup/restore process management
692     */
693    String mBackupAppName = null;
694    BackupRecord mBackupTarget = null;
695
696    /**
697     * List of PendingThumbnailsRecord objects of clients who are still
698     * waiting to receive all of the thumbnails for a task.
699     */
700    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
701            new ArrayList<PendingThumbnailsRecord>();
702
703    final ProviderMap mProviderMap;
704
705    /**
706     * List of content providers who have clients waiting for them.  The
707     * application is currently being launched and the provider will be
708     * removed from this list once it is published.
709     */
710    final ArrayList<ContentProviderRecord> mLaunchingProviders
711            = new ArrayList<ContentProviderRecord>();
712
713    /**
714     * File storing persisted {@link #mGrantedUriPermissions}.
715     */
716    private final AtomicFile mGrantFile;
717
718    /** XML constants used in {@link #mGrantFile} */
719    private static final String TAG_URI_GRANTS = "uri-grants";
720    private static final String TAG_URI_GRANT = "uri-grant";
721    private static final String ATTR_USER_HANDLE = "userHandle";
722    private static final String ATTR_SOURCE_PKG = "sourcePkg";
723    private static final String ATTR_TARGET_PKG = "targetPkg";
724    private static final String ATTR_URI = "uri";
725    private static final String ATTR_MODE_FLAGS = "modeFlags";
726    private static final String ATTR_CREATED_TIME = "createdTime";
727
728    /**
729     * Global set of specific {@link Uri} permissions that have been granted.
730     * This optimized lookup structure maps from {@link UriPermission#targetUid}
731     * to {@link UriPermission#uri} to {@link UriPermission}.
732     */
733    @GuardedBy("this")
734    private final SparseArray<ArrayMap<Uri, UriPermission>>
735            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
736
737    CoreSettingsObserver mCoreSettingsObserver;
738
739    /**
740     * Thread-local storage used to carry caller permissions over through
741     * indirect content-provider access.
742     */
743    private class Identity {
744        public int pid;
745        public int uid;
746
747        Identity(int _pid, int _uid) {
748            pid = _pid;
749            uid = _uid;
750        }
751    }
752
753    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
754
755    /**
756     * All information we have collected about the runtime performance of
757     * any user id that can impact battery performance.
758     */
759    final BatteryStatsService mBatteryStatsService;
760
761    /**
762     * Information about component usage
763     */
764    final UsageStatsService mUsageStatsService;
765
766    /**
767     * Information about and control over application operations
768     */
769    final AppOpsService mAppOpsService;
770
771    /**
772     * Current configuration information.  HistoryRecord objects are given
773     * a reference to this object to indicate which configuration they are
774     * currently running in, so this object must be kept immutable.
775     */
776    Configuration mConfiguration = new Configuration();
777
778    /**
779     * Current sequencing integer of the configuration, for skipping old
780     * configurations.
781     */
782    int mConfigurationSeq = 0;
783
784    /**
785     * Hardware-reported OpenGLES version.
786     */
787    final int GL_ES_VERSION;
788
789    /**
790     * List of initialization arguments to pass to all processes when binding applications to them.
791     * For example, references to the commonly used services.
792     */
793    HashMap<String, IBinder> mAppBindArgs;
794
795    /**
796     * Temporary to avoid allocations.  Protected by main lock.
797     */
798    final StringBuilder mStringBuilder = new StringBuilder(256);
799
800    /**
801     * Used to control how we initialize the service.
802     */
803    boolean mStartRunning = false;
804    ComponentName mTopComponent;
805    String mTopAction;
806    String mTopData;
807    boolean mProcessesReady = false;
808    boolean mSystemReady = false;
809    boolean mBooting = false;
810    boolean mWaitingUpdate = false;
811    boolean mDidUpdate = false;
812    boolean mOnBattery = false;
813    boolean mLaunchWarningShown = false;
814
815    Context mContext;
816
817    int mFactoryTest;
818
819    boolean mCheckedForSetup;
820
821    /**
822     * The time at which we will allow normal application switches again,
823     * after a call to {@link #stopAppSwitches()}.
824     */
825    long mAppSwitchesAllowedTime;
826
827    /**
828     * This is set to true after the first switch after mAppSwitchesAllowedTime
829     * is set; any switches after that will clear the time.
830     */
831    boolean mDidAppSwitch;
832
833    /**
834     * Last time (in realtime) at which we checked for power usage.
835     */
836    long mLastPowerCheckRealtime;
837
838    /**
839     * Last time (in uptime) at which we checked for power usage.
840     */
841    long mLastPowerCheckUptime;
842
843    /**
844     * Set while we are wanting to sleep, to prevent any
845     * activities from being started/resumed.
846     */
847    boolean mSleeping = false;
848
849    /**
850     * State of external calls telling us if the device is asleep.
851     */
852    boolean mWentToSleep = false;
853
854    /**
855     * State of external call telling us if the lock screen is shown.
856     */
857    boolean mLockScreenShown = false;
858
859    /**
860     * Set if we are shutting down the system, similar to sleeping.
861     */
862    boolean mShuttingDown = false;
863
864    /**
865     * Current sequence id for oom_adj computation traversal.
866     */
867    int mAdjSeq = 0;
868
869    /**
870     * Current sequence id for process LRU updating.
871     */
872    int mLruSeq = 0;
873
874    /**
875     * Keep track of the non-cached/empty process we last found, to help
876     * determine how to distribute cached/empty processes next time.
877     */
878    int mNumNonCachedProcs = 0;
879
880    /**
881     * Keep track of the number of cached hidden procs, to balance oom adj
882     * distribution between those and empty procs.
883     */
884    int mNumCachedHiddenProcs = 0;
885
886    /**
887     * Keep track of the number of service processes we last found, to
888     * determine on the next iteration which should be B services.
889     */
890    int mNumServiceProcs = 0;
891    int mNewNumAServiceProcs = 0;
892    int mNewNumServiceProcs = 0;
893
894    /**
895     * Allow the current computed overall memory level of the system to go down?
896     * This is set to false when we are killing processes for reasons other than
897     * memory management, so that the now smaller process list will not be taken as
898     * an indication that memory is tighter.
899     */
900    boolean mAllowLowerMemLevel = false;
901
902    /**
903     * The last computed memory level, for holding when we are in a state that
904     * processes are going away for other reasons.
905     */
906    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
907
908    /**
909     * The last total number of process we have, to determine if changes actually look
910     * like a shrinking number of process due to lower RAM.
911     */
912    int mLastNumProcesses;
913
914    /**
915     * The uptime of the last time we performed idle maintenance.
916     */
917    long mLastIdleTime = SystemClock.uptimeMillis();
918
919    /**
920     * Total time spent with RAM that has been added in the past since the last idle time.
921     */
922    long mLowRamTimeSinceLastIdle = 0;
923
924    /**
925     * If RAM is currently low, when that horrible situatin started.
926     */
927    long mLowRamStartTime = 0;
928
929    /**
930     * This is set if we had to do a delayed dexopt of an app before launching
931     * it, to increasing the ANR timeouts in that case.
932     */
933    boolean mDidDexOpt;
934
935    String mDebugApp = null;
936    boolean mWaitForDebugger = false;
937    boolean mDebugTransient = false;
938    String mOrigDebugApp = null;
939    boolean mOrigWaitForDebugger = false;
940    boolean mAlwaysFinishActivities = false;
941    IActivityController mController = null;
942    String mProfileApp = null;
943    ProcessRecord mProfileProc = null;
944    String mProfileFile;
945    ParcelFileDescriptor mProfileFd;
946    int mProfileType = 0;
947    boolean mAutoStopProfiler = false;
948    String mOpenGlTraceApp = null;
949
950    static class ProcessChangeItem {
951        static final int CHANGE_ACTIVITIES = 1<<0;
952        static final int CHANGE_IMPORTANCE= 1<<1;
953        int changes;
954        int uid;
955        int pid;
956        int importance;
957        boolean foregroundActivities;
958    }
959
960    final RemoteCallbackList<IProcessObserver> mProcessObservers
961            = new RemoteCallbackList<IProcessObserver>();
962    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
963
964    final ArrayList<ProcessChangeItem> mPendingProcessChanges
965            = new ArrayList<ProcessChangeItem>();
966    final ArrayList<ProcessChangeItem> mAvailProcessChanges
967            = new ArrayList<ProcessChangeItem>();
968
969    /**
970     * Runtime CPU use collection thread.  This object's lock is used to
971     * protect all related state.
972     */
973    final Thread mProcessCpuThread;
974
975    /**
976     * Used to collect process stats when showing not responding dialog.
977     * Protected by mProcessCpuThread.
978     */
979    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
980            MONITOR_THREAD_CPU_USAGE);
981    final AtomicLong mLastCpuTime = new AtomicLong(0);
982    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
983
984    long mLastWriteTime = 0;
985
986    /**
987     * Used to retain an update lock when the foreground activity is in
988     * immersive mode.
989     */
990    final UpdateLock mUpdateLock = new UpdateLock("immersive");
991
992    /**
993     * Set to true after the system has finished booting.
994     */
995    boolean mBooted = false;
996
997    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
998    int mProcessLimitOverride = -1;
999
1000    WindowManagerService mWindowManager;
1001
1002    static ActivityManagerService sSelf;
1003    static ActivityThread sSystemThread;
1004
1005    int mCurrentUserId = 0;
1006    private UserManagerService mUserManager;
1007
1008    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1009        final ProcessRecord mApp;
1010        final int mPid;
1011        final IApplicationThread mAppThread;
1012
1013        AppDeathRecipient(ProcessRecord app, int pid,
1014                IApplicationThread thread) {
1015            if (localLOGV) Slog.v(
1016                TAG, "New death recipient " + this
1017                + " for thread " + thread.asBinder());
1018            mApp = app;
1019            mPid = pid;
1020            mAppThread = thread;
1021        }
1022
1023        @Override
1024        public void binderDied() {
1025            if (localLOGV) Slog.v(
1026                TAG, "Death received in " + this
1027                + " for thread " + mAppThread.asBinder());
1028            synchronized(ActivityManagerService.this) {
1029                appDiedLocked(mApp, mPid, mAppThread);
1030            }
1031        }
1032    }
1033
1034    static final int SHOW_ERROR_MSG = 1;
1035    static final int SHOW_NOT_RESPONDING_MSG = 2;
1036    static final int SHOW_FACTORY_ERROR_MSG = 3;
1037    static final int UPDATE_CONFIGURATION_MSG = 4;
1038    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1039    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1040    static final int SERVICE_TIMEOUT_MSG = 12;
1041    static final int UPDATE_TIME_ZONE = 13;
1042    static final int SHOW_UID_ERROR_MSG = 14;
1043    static final int IM_FEELING_LUCKY_MSG = 15;
1044    static final int PROC_START_TIMEOUT_MSG = 20;
1045    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1046    static final int KILL_APPLICATION_MSG = 22;
1047    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1048    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1049    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1050    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1051    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1052    static final int CLEAR_DNS_CACHE_MSG = 28;
1053    static final int UPDATE_HTTP_PROXY_MSG = 29;
1054    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1055    static final int DISPATCH_PROCESSES_CHANGED = 31;
1056    static final int DISPATCH_PROCESS_DIED = 32;
1057    static final int REPORT_MEM_USAGE_MSG = 33;
1058    static final int REPORT_USER_SWITCH_MSG = 34;
1059    static final int CONTINUE_USER_SWITCH_MSG = 35;
1060    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1061    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1062    static final int PERSIST_URI_GRANTS_MSG = 38;
1063    static final int REQUEST_ALL_PSS_MSG = 39;
1064
1065    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1066    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1067    static final int FIRST_COMPAT_MODE_MSG = 300;
1068    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1069
1070    AlertDialog mUidAlert;
1071    CompatModeDialog mCompatModeDialog;
1072    long mLastMemUsageReportTime = 0;
1073
1074    /**
1075     * Flag whether the current user is a "monkey", i.e. whether
1076     * the UI is driven by a UI automation tool.
1077     */
1078    private boolean mUserIsMonkey;
1079
1080    final ServiceThread mHandlerThread;
1081    final MainHandler mHandler;
1082
1083    final class MainHandler extends Handler {
1084        public MainHandler(Looper looper) {
1085            super(looper, null, true);
1086        }
1087
1088        @Override
1089        public void handleMessage(Message msg) {
1090            switch (msg.what) {
1091            case SHOW_ERROR_MSG: {
1092                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1093                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1094                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1095                synchronized (ActivityManagerService.this) {
1096                    ProcessRecord proc = (ProcessRecord)data.get("app");
1097                    AppErrorResult res = (AppErrorResult) data.get("result");
1098                    if (proc != null && proc.crashDialog != null) {
1099                        Slog.e(TAG, "App already has crash dialog: " + proc);
1100                        if (res != null) {
1101                            res.set(0);
1102                        }
1103                        return;
1104                    }
1105                    if (!showBackground && UserHandle.getAppId(proc.uid)
1106                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1107                            && proc.pid != MY_PID) {
1108                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1109                        if (res != null) {
1110                            res.set(0);
1111                        }
1112                        return;
1113                    }
1114                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1115                        Dialog d = new AppErrorDialog(mContext,
1116                                ActivityManagerService.this, res, proc);
1117                        d.show();
1118                        proc.crashDialog = d;
1119                    } else {
1120                        // The device is asleep, so just pretend that the user
1121                        // saw a crash dialog and hit "force quit".
1122                        if (res != null) {
1123                            res.set(0);
1124                        }
1125                    }
1126                }
1127
1128                ensureBootCompleted();
1129            } break;
1130            case SHOW_NOT_RESPONDING_MSG: {
1131                synchronized (ActivityManagerService.this) {
1132                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1133                    ProcessRecord proc = (ProcessRecord)data.get("app");
1134                    if (proc != null && proc.anrDialog != null) {
1135                        Slog.e(TAG, "App already has anr dialog: " + proc);
1136                        return;
1137                    }
1138
1139                    Intent intent = new Intent("android.intent.action.ANR");
1140                    if (!mProcessesReady) {
1141                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1142                                | Intent.FLAG_RECEIVER_FOREGROUND);
1143                    }
1144                    broadcastIntentLocked(null, null, intent,
1145                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1146                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1147
1148                    if (mShowDialogs) {
1149                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1150                                mContext, proc, (ActivityRecord)data.get("activity"),
1151                                msg.arg1 != 0);
1152                        d.show();
1153                        proc.anrDialog = d;
1154                    } else {
1155                        // Just kill the app if there is no dialog to be shown.
1156                        killAppAtUsersRequest(proc, null);
1157                    }
1158                }
1159
1160                ensureBootCompleted();
1161            } break;
1162            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1163                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1164                synchronized (ActivityManagerService.this) {
1165                    ProcessRecord proc = (ProcessRecord) data.get("app");
1166                    if (proc == null) {
1167                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1168                        break;
1169                    }
1170                    if (proc.crashDialog != null) {
1171                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1172                        return;
1173                    }
1174                    AppErrorResult res = (AppErrorResult) data.get("result");
1175                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1176                        Dialog d = new StrictModeViolationDialog(mContext,
1177                                ActivityManagerService.this, res, proc);
1178                        d.show();
1179                        proc.crashDialog = d;
1180                    } else {
1181                        // The device is asleep, so just pretend that the user
1182                        // saw a crash dialog and hit "force quit".
1183                        res.set(0);
1184                    }
1185                }
1186                ensureBootCompleted();
1187            } break;
1188            case SHOW_FACTORY_ERROR_MSG: {
1189                Dialog d = new FactoryErrorDialog(
1190                    mContext, msg.getData().getCharSequence("msg"));
1191                d.show();
1192                ensureBootCompleted();
1193            } break;
1194            case UPDATE_CONFIGURATION_MSG: {
1195                final ContentResolver resolver = mContext.getContentResolver();
1196                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1197            } break;
1198            case GC_BACKGROUND_PROCESSES_MSG: {
1199                synchronized (ActivityManagerService.this) {
1200                    performAppGcsIfAppropriateLocked();
1201                }
1202            } break;
1203            case WAIT_FOR_DEBUGGER_MSG: {
1204                synchronized (ActivityManagerService.this) {
1205                    ProcessRecord app = (ProcessRecord)msg.obj;
1206                    if (msg.arg1 != 0) {
1207                        if (!app.waitedForDebugger) {
1208                            Dialog d = new AppWaitingForDebuggerDialog(
1209                                    ActivityManagerService.this,
1210                                    mContext, app);
1211                            app.waitDialog = d;
1212                            app.waitedForDebugger = true;
1213                            d.show();
1214                        }
1215                    } else {
1216                        if (app.waitDialog != null) {
1217                            app.waitDialog.dismiss();
1218                            app.waitDialog = null;
1219                        }
1220                    }
1221                }
1222            } break;
1223            case SERVICE_TIMEOUT_MSG: {
1224                if (mDidDexOpt) {
1225                    mDidDexOpt = false;
1226                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1227                    nmsg.obj = msg.obj;
1228                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1229                    return;
1230                }
1231                mServices.serviceTimeout((ProcessRecord)msg.obj);
1232            } break;
1233            case UPDATE_TIME_ZONE: {
1234                synchronized (ActivityManagerService.this) {
1235                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1236                        ProcessRecord r = mLruProcesses.get(i);
1237                        if (r.thread != null) {
1238                            try {
1239                                r.thread.updateTimeZone();
1240                            } catch (RemoteException ex) {
1241                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1242                            }
1243                        }
1244                    }
1245                }
1246            } break;
1247            case CLEAR_DNS_CACHE_MSG: {
1248                synchronized (ActivityManagerService.this) {
1249                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1250                        ProcessRecord r = mLruProcesses.get(i);
1251                        if (r.thread != null) {
1252                            try {
1253                                r.thread.clearDnsCache();
1254                            } catch (RemoteException ex) {
1255                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1256                            }
1257                        }
1258                    }
1259                }
1260            } break;
1261            case UPDATE_HTTP_PROXY_MSG: {
1262                ProxyProperties proxy = (ProxyProperties)msg.obj;
1263                String host = "";
1264                String port = "";
1265                String exclList = "";
1266                String pacFileUrl = null;
1267                if (proxy != null) {
1268                    host = proxy.getHost();
1269                    port = Integer.toString(proxy.getPort());
1270                    exclList = proxy.getExclusionList();
1271                    pacFileUrl = proxy.getPacFileUrl();
1272                }
1273                synchronized (ActivityManagerService.this) {
1274                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1275                        ProcessRecord r = mLruProcesses.get(i);
1276                        if (r.thread != null) {
1277                            try {
1278                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1279                            } catch (RemoteException ex) {
1280                                Slog.w(TAG, "Failed to update http proxy for: " +
1281                                        r.info.processName);
1282                            }
1283                        }
1284                    }
1285                }
1286            } break;
1287            case SHOW_UID_ERROR_MSG: {
1288                String title = "System UIDs Inconsistent";
1289                String text = "UIDs on the system are inconsistent, you need to wipe your"
1290                        + " data partition or your device will be unstable.";
1291                Log.e(TAG, title + ": " + text);
1292                if (mShowDialogs) {
1293                    // XXX This is a temporary dialog, no need to localize.
1294                    AlertDialog d = new BaseErrorDialog(mContext);
1295                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1296                    d.setCancelable(false);
1297                    d.setTitle(title);
1298                    d.setMessage(text);
1299                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1300                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1301                    mUidAlert = d;
1302                    d.show();
1303                }
1304            } break;
1305            case IM_FEELING_LUCKY_MSG: {
1306                if (mUidAlert != null) {
1307                    mUidAlert.dismiss();
1308                    mUidAlert = null;
1309                }
1310            } break;
1311            case PROC_START_TIMEOUT_MSG: {
1312                if (mDidDexOpt) {
1313                    mDidDexOpt = false;
1314                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1315                    nmsg.obj = msg.obj;
1316                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1317                    return;
1318                }
1319                ProcessRecord app = (ProcessRecord)msg.obj;
1320                synchronized (ActivityManagerService.this) {
1321                    processStartTimedOutLocked(app);
1322                }
1323            } break;
1324            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1325                synchronized (ActivityManagerService.this) {
1326                    doPendingActivityLaunchesLocked(true);
1327                }
1328            } break;
1329            case KILL_APPLICATION_MSG: {
1330                synchronized (ActivityManagerService.this) {
1331                    int appid = msg.arg1;
1332                    boolean restart = (msg.arg2 == 1);
1333                    Bundle bundle = (Bundle)msg.obj;
1334                    String pkg = bundle.getString("pkg");
1335                    String reason = bundle.getString("reason");
1336                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1337                            false, UserHandle.USER_ALL, reason);
1338                }
1339            } break;
1340            case FINALIZE_PENDING_INTENT_MSG: {
1341                ((PendingIntentRecord)msg.obj).completeFinalize();
1342            } break;
1343            case POST_HEAVY_NOTIFICATION_MSG: {
1344                INotificationManager inm = NotificationManager.getService();
1345                if (inm == null) {
1346                    return;
1347                }
1348
1349                ActivityRecord root = (ActivityRecord)msg.obj;
1350                ProcessRecord process = root.app;
1351                if (process == null) {
1352                    return;
1353                }
1354
1355                try {
1356                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1357                    String text = mContext.getString(R.string.heavy_weight_notification,
1358                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1359                    Notification notification = new Notification();
1360                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1361                    notification.when = 0;
1362                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1363                    notification.tickerText = text;
1364                    notification.defaults = 0; // please be quiet
1365                    notification.sound = null;
1366                    notification.vibrate = null;
1367                    notification.setLatestEventInfo(context, text,
1368                            mContext.getText(R.string.heavy_weight_notification_detail),
1369                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1370                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1371                                    new UserHandle(root.userId)));
1372
1373                    try {
1374                        int[] outId = new int[1];
1375                        inm.enqueueNotificationWithTag("android", "android", null,
1376                                R.string.heavy_weight_notification,
1377                                notification, outId, root.userId);
1378                    } catch (RuntimeException e) {
1379                        Slog.w(ActivityManagerService.TAG,
1380                                "Error showing notification for heavy-weight app", e);
1381                    } catch (RemoteException e) {
1382                    }
1383                } catch (NameNotFoundException e) {
1384                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1385                }
1386            } break;
1387            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1388                INotificationManager inm = NotificationManager.getService();
1389                if (inm == null) {
1390                    return;
1391                }
1392                try {
1393                    inm.cancelNotificationWithTag("android", null,
1394                            R.string.heavy_weight_notification,  msg.arg1);
1395                } catch (RuntimeException e) {
1396                    Slog.w(ActivityManagerService.TAG,
1397                            "Error canceling notification for service", e);
1398                } catch (RemoteException e) {
1399                }
1400            } break;
1401            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1402                synchronized (ActivityManagerService.this) {
1403                    checkExcessivePowerUsageLocked(true);
1404                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1405                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1406                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1407                }
1408            } break;
1409            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    ActivityRecord ar = (ActivityRecord)msg.obj;
1412                    if (mCompatModeDialog != null) {
1413                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1414                                ar.info.applicationInfo.packageName)) {
1415                            return;
1416                        }
1417                        mCompatModeDialog.dismiss();
1418                        mCompatModeDialog = null;
1419                    }
1420                    if (ar != null && false) {
1421                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1422                                ar.packageName)) {
1423                            int mode = mCompatModePackages.computeCompatModeLocked(
1424                                    ar.info.applicationInfo);
1425                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1426                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1427                                mCompatModeDialog = new CompatModeDialog(
1428                                        ActivityManagerService.this, mContext,
1429                                        ar.info.applicationInfo);
1430                                mCompatModeDialog.show();
1431                            }
1432                        }
1433                    }
1434                }
1435                break;
1436            }
1437            case DISPATCH_PROCESSES_CHANGED: {
1438                dispatchProcessesChanged();
1439                break;
1440            }
1441            case DISPATCH_PROCESS_DIED: {
1442                final int pid = msg.arg1;
1443                final int uid = msg.arg2;
1444                dispatchProcessDied(pid, uid);
1445                break;
1446            }
1447            case REPORT_MEM_USAGE_MSG: {
1448                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1449                Thread thread = new Thread() {
1450                    @Override public void run() {
1451                        final SparseArray<ProcessMemInfo> infoMap
1452                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1453                        for (int i=0, N=memInfos.size(); i<N; i++) {
1454                            ProcessMemInfo mi = memInfos.get(i);
1455                            infoMap.put(mi.pid, mi);
1456                        }
1457                        updateCpuStatsNow();
1458                        synchronized (mProcessCpuThread) {
1459                            final int N = mProcessCpuTracker.countStats();
1460                            for (int i=0; i<N; i++) {
1461                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1462                                if (st.vsize > 0) {
1463                                    long pss = Debug.getPss(st.pid, null);
1464                                    if (pss > 0) {
1465                                        if (infoMap.indexOfKey(st.pid) < 0) {
1466                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1467                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1468                                            mi.pss = pss;
1469                                            memInfos.add(mi);
1470                                        }
1471                                    }
1472                                }
1473                            }
1474                        }
1475
1476                        long totalPss = 0;
1477                        for (int i=0, N=memInfos.size(); i<N; i++) {
1478                            ProcessMemInfo mi = memInfos.get(i);
1479                            if (mi.pss == 0) {
1480                                mi.pss = Debug.getPss(mi.pid, null);
1481                            }
1482                            totalPss += mi.pss;
1483                        }
1484                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1485                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1486                                if (lhs.oomAdj != rhs.oomAdj) {
1487                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1488                                }
1489                                if (lhs.pss != rhs.pss) {
1490                                    return lhs.pss < rhs.pss ? 1 : -1;
1491                                }
1492                                return 0;
1493                            }
1494                        });
1495
1496                        StringBuilder tag = new StringBuilder(128);
1497                        StringBuilder stack = new StringBuilder(128);
1498                        tag.append("Low on memory -- ");
1499                        appendMemBucket(tag, totalPss, "total", false);
1500                        appendMemBucket(stack, totalPss, "total", true);
1501
1502                        StringBuilder logBuilder = new StringBuilder(1024);
1503                        logBuilder.append("Low on memory:\n");
1504
1505                        boolean firstLine = true;
1506                        int lastOomAdj = Integer.MIN_VALUE;
1507                        for (int i=0, N=memInfos.size(); i<N; i++) {
1508                            ProcessMemInfo mi = memInfos.get(i);
1509
1510                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1511                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1512                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1513                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1514                                if (lastOomAdj != mi.oomAdj) {
1515                                    lastOomAdj = mi.oomAdj;
1516                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1517                                        tag.append(" / ");
1518                                    }
1519                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1520                                        if (firstLine) {
1521                                            stack.append(":");
1522                                            firstLine = false;
1523                                        }
1524                                        stack.append("\n\t at ");
1525                                    } else {
1526                                        stack.append("$");
1527                                    }
1528                                } else {
1529                                    tag.append(" ");
1530                                    stack.append("$");
1531                                }
1532                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1533                                    appendMemBucket(tag, mi.pss, mi.name, false);
1534                                }
1535                                appendMemBucket(stack, mi.pss, mi.name, true);
1536                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1537                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1538                                    stack.append("(");
1539                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1540                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1541                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1542                                            stack.append(":");
1543                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1544                                        }
1545                                    }
1546                                    stack.append(")");
1547                                }
1548                            }
1549
1550                            logBuilder.append("  ");
1551                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1552                            logBuilder.append(' ');
1553                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1554                            logBuilder.append(' ');
1555                            ProcessList.appendRamKb(logBuilder, mi.pss);
1556                            logBuilder.append(" kB: ");
1557                            logBuilder.append(mi.name);
1558                            logBuilder.append(" (");
1559                            logBuilder.append(mi.pid);
1560                            logBuilder.append(") ");
1561                            logBuilder.append(mi.adjType);
1562                            logBuilder.append('\n');
1563                            if (mi.adjReason != null) {
1564                                logBuilder.append("                      ");
1565                                logBuilder.append(mi.adjReason);
1566                                logBuilder.append('\n');
1567                            }
1568                        }
1569
1570                        logBuilder.append("           ");
1571                        ProcessList.appendRamKb(logBuilder, totalPss);
1572                        logBuilder.append(" kB: TOTAL\n");
1573
1574                        long[] infos = new long[Debug.MEMINFO_COUNT];
1575                        Debug.getMemInfo(infos);
1576                        logBuilder.append("  MemInfo: ");
1577                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1578                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1579                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1580                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1581                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1582                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1583                            logBuilder.append("  ZRAM: ");
1584                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1585                            logBuilder.append(" kB RAM, ");
1586                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1587                            logBuilder.append(" kB swap total, ");
1588                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1589                            logBuilder.append(" kB swap free\n");
1590                        }
1591                        Slog.i(TAG, logBuilder.toString());
1592
1593                        StringBuilder dropBuilder = new StringBuilder(1024);
1594                        /*
1595                        StringWriter oomSw = new StringWriter();
1596                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1597                        StringWriter catSw = new StringWriter();
1598                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1599                        String[] emptyArgs = new String[] { };
1600                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1601                        oomPw.flush();
1602                        String oomString = oomSw.toString();
1603                        */
1604                        dropBuilder.append(stack);
1605                        dropBuilder.append('\n');
1606                        dropBuilder.append('\n');
1607                        dropBuilder.append(logBuilder);
1608                        dropBuilder.append('\n');
1609                        /*
1610                        dropBuilder.append(oomString);
1611                        dropBuilder.append('\n');
1612                        */
1613                        StringWriter catSw = new StringWriter();
1614                        synchronized (ActivityManagerService.this) {
1615                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1616                            String[] emptyArgs = new String[] { };
1617                            catPw.println();
1618                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1619                            catPw.println();
1620                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1621                                    false, false, null);
1622                            catPw.println();
1623                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1624                            catPw.flush();
1625                        }
1626                        dropBuilder.append(catSw.toString());
1627                        addErrorToDropBox("lowmem", null, "system_server", null,
1628                                null, tag.toString(), dropBuilder.toString(), null, null);
1629                        //Slog.i(TAG, "Sent to dropbox:");
1630                        //Slog.i(TAG, dropBuilder.toString());
1631                        synchronized (ActivityManagerService.this) {
1632                            long now = SystemClock.uptimeMillis();
1633                            if (mLastMemUsageReportTime < now) {
1634                                mLastMemUsageReportTime = now;
1635                            }
1636                        }
1637                    }
1638                };
1639                thread.start();
1640                break;
1641            }
1642            case REPORT_USER_SWITCH_MSG: {
1643                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1644                break;
1645            }
1646            case CONTINUE_USER_SWITCH_MSG: {
1647                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1648                break;
1649            }
1650            case USER_SWITCH_TIMEOUT_MSG: {
1651                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1652                break;
1653            }
1654            case IMMERSIVE_MODE_LOCK_MSG: {
1655                final boolean nextState = (msg.arg1 != 0);
1656                if (mUpdateLock.isHeld() != nextState) {
1657                    if (DEBUG_IMMERSIVE) {
1658                        final ActivityRecord r = (ActivityRecord) msg.obj;
1659                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1660                    }
1661                    if (nextState) {
1662                        mUpdateLock.acquire();
1663                    } else {
1664                        mUpdateLock.release();
1665                    }
1666                }
1667                break;
1668            }
1669            case PERSIST_URI_GRANTS_MSG: {
1670                writeGrantedUriPermissions();
1671                break;
1672            }
1673            case REQUEST_ALL_PSS_MSG: {
1674                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1675                break;
1676            }
1677            }
1678        }
1679    };
1680
1681    static final int COLLECT_PSS_BG_MSG = 1;
1682
1683    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1684        @Override
1685        public void handleMessage(Message msg) {
1686            switch (msg.what) {
1687            case COLLECT_PSS_BG_MSG: {
1688                int i=0, num=0;
1689                long start = SystemClock.uptimeMillis();
1690                long[] tmp = new long[1];
1691                do {
1692                    ProcessRecord proc;
1693                    int procState;
1694                    int pid;
1695                    synchronized (ActivityManagerService.this) {
1696                        if (i >= mPendingPssProcesses.size()) {
1697                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1698                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1699                            mPendingPssProcesses.clear();
1700                            return;
1701                        }
1702                        proc = mPendingPssProcesses.get(i);
1703                        procState = proc.pssProcState;
1704                        if (proc.thread != null && procState == proc.setProcState) {
1705                            pid = proc.pid;
1706                        } else {
1707                            proc = null;
1708                            pid = 0;
1709                        }
1710                        i++;
1711                    }
1712                    if (proc != null) {
1713                        long pss = Debug.getPss(pid, tmp);
1714                        synchronized (ActivityManagerService.this) {
1715                            if (proc.thread != null && proc.setProcState == procState
1716                                    && proc.pid == pid) {
1717                                num++;
1718                                proc.lastPssTime = SystemClock.uptimeMillis();
1719                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1720                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1721                                        + ": " + pss + " lastPss=" + proc.lastPss
1722                                        + " state=" + ProcessList.makeProcStateString(procState));
1723                                if (proc.initialIdlePss == 0) {
1724                                    proc.initialIdlePss = pss;
1725                                }
1726                                proc.lastPss = pss;
1727                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1728                                    proc.lastCachedPss = pss;
1729                                }
1730                            }
1731                        }
1732                    }
1733                } while (true);
1734            }
1735            }
1736        }
1737    };
1738
1739    public static void setSystemProcess() {
1740        try {
1741            ActivityManagerService m = sSelf;
1742
1743            ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
1744            ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
1745            ServiceManager.addService("meminfo", new MemBinder(m));
1746            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1747            ServiceManager.addService("dbinfo", new DbBinder(m));
1748            if (MONITOR_CPU_USAGE) {
1749                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1750            }
1751            ServiceManager.addService("permission", new PermissionController(m));
1752
1753            ApplicationInfo info =
1754                sSelf.mContext.getPackageManager().getApplicationInfo(
1755                            "android", STOCK_PM_FLAGS);
1756            sSystemThread.installSystemApplicationInfo(info);
1757
1758            synchronized (sSelf) {
1759                ProcessRecord app = sSelf.newProcessRecordLocked(info,
1760                        info.processName, false);
1761                app.persistent = true;
1762                app.pid = MY_PID;
1763                app.maxAdj = ProcessList.SYSTEM_ADJ;
1764                app.makeActive(sSystemThread.getApplicationThread(), sSelf.mProcessStats);
1765                sSelf.mProcessNames.put(app.processName, app.uid, app);
1766                synchronized (sSelf.mPidsSelfLocked) {
1767                    sSelf.mPidsSelfLocked.put(app.pid, app);
1768                }
1769                sSelf.updateLruProcessLocked(app, false, null);
1770                sSelf.updateOomAdjLocked();
1771            }
1772        } catch (PackageManager.NameNotFoundException e) {
1773            throw new RuntimeException(
1774                    "Unable to find android system package", e);
1775        }
1776    }
1777
1778    public void setWindowManager(WindowManagerService wm) {
1779        mWindowManager = wm;
1780        mStackSupervisor.setWindowManager(wm);
1781    }
1782
1783    public void startObservingNativeCrashes() {
1784        final NativeCrashListener ncl = new NativeCrashListener();
1785        ncl.start();
1786    }
1787
1788    public static ActivityManagerService self() {
1789        return sSelf;
1790    }
1791
1792    public IAppOpsService getAppOpsService() {
1793        return mAppOpsService;
1794    }
1795
1796    static class MemBinder extends Binder {
1797        ActivityManagerService mActivityManagerService;
1798        MemBinder(ActivityManagerService activityManagerService) {
1799            mActivityManagerService = activityManagerService;
1800        }
1801
1802        @Override
1803        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1804            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1805                    != PackageManager.PERMISSION_GRANTED) {
1806                pw.println("Permission Denial: can't dump meminfo from from pid="
1807                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1808                        + " without permission " + android.Manifest.permission.DUMP);
1809                return;
1810            }
1811
1812            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1813        }
1814    }
1815
1816    static class GraphicsBinder extends Binder {
1817        ActivityManagerService mActivityManagerService;
1818        GraphicsBinder(ActivityManagerService activityManagerService) {
1819            mActivityManagerService = activityManagerService;
1820        }
1821
1822        @Override
1823        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1824            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1825                    != PackageManager.PERMISSION_GRANTED) {
1826                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1827                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1828                        + " without permission " + android.Manifest.permission.DUMP);
1829                return;
1830            }
1831
1832            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1833        }
1834    }
1835
1836    static class DbBinder extends Binder {
1837        ActivityManagerService mActivityManagerService;
1838        DbBinder(ActivityManagerService activityManagerService) {
1839            mActivityManagerService = activityManagerService;
1840        }
1841
1842        @Override
1843        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1844            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1845                    != PackageManager.PERMISSION_GRANTED) {
1846                pw.println("Permission Denial: can't dump dbinfo from from pid="
1847                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1848                        + " without permission " + android.Manifest.permission.DUMP);
1849                return;
1850            }
1851
1852            mActivityManagerService.dumpDbInfo(fd, pw, args);
1853        }
1854    }
1855
1856    static class CpuBinder extends Binder {
1857        ActivityManagerService mActivityManagerService;
1858        CpuBinder(ActivityManagerService activityManagerService) {
1859            mActivityManagerService = activityManagerService;
1860        }
1861
1862        @Override
1863        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1864            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1865                    != PackageManager.PERMISSION_GRANTED) {
1866                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1867                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1868                        + " without permission " + android.Manifest.permission.DUMP);
1869                return;
1870            }
1871
1872            synchronized (mActivityManagerService.mProcessCpuThread) {
1873                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1874                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1875                        SystemClock.uptimeMillis()));
1876            }
1877        }
1878    }
1879
1880    public static class Lifecycle extends SystemService {
1881        private ActivityManagerService mService;
1882
1883        @Override
1884        public void onCreate(Context context) {
1885            mService = new ActivityManagerService(context);
1886        }
1887
1888        @Override
1889        public void onStart() {
1890            mService.start();
1891        }
1892    }
1893
1894    // Note: This method is invoked on the main thread but may need to attach various
1895    // handlers to other threads.  So take care to be explicit about the looper.
1896    public ActivityManagerService(Context systemContext) {
1897        sSelf = this;
1898        sSystemThread = ActivityThread.currentActivityThread();
1899
1900        mContext = systemContext;
1901        mFactoryTest = FactoryTest.getMode();
1902
1903        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1904
1905        mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND);
1906        mHandlerThread.start();
1907        mHandler = new MainHandler(mHandlerThread.getLooper());
1908
1909        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1910                "foreground", BROADCAST_FG_TIMEOUT, false);
1911        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1912                "background", BROADCAST_BG_TIMEOUT, true);
1913        mBroadcastQueues[0] = mFgBroadcastQueue;
1914        mBroadcastQueues[1] = mBgBroadcastQueue;
1915
1916        mServices = new ActiveServices(this);
1917        mProviderMap = new ProviderMap(this);
1918
1919        // TODO: Move creation of battery stats service outside of activity manager service.
1920        File dataDir = Environment.getDataDirectory();
1921        File systemDir = new File(dataDir, "system");
1922        systemDir.mkdirs();
1923        mBatteryStatsService = new BatteryStatsService(new File(
1924                systemDir, "batterystats.bin").toString(), mHandler);
1925        mBatteryStatsService.getActiveStatistics().readLocked();
1926        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1927        mOnBattery = DEBUG_POWER ? true
1928                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1929        mBatteryStatsService.getActiveStatistics().setCallback(this);
1930
1931        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1932
1933        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1934        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1935
1936        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1937
1938        // User 0 is the first and only user that runs at boot.
1939        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1940        mUserLru.add(Integer.valueOf(0));
1941        updateStartedUserArrayLocked();
1942
1943        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1944            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1945
1946        mConfiguration.setToDefaults();
1947        mConfiguration.setLocale(Locale.getDefault());
1948
1949        mConfigurationSeq = mConfiguration.seq = 1;
1950        mProcessCpuTracker.init();
1951
1952        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1953        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1954        mStackSupervisor = new ActivityStackSupervisor(this);
1955
1956        mProcessCpuThread = new Thread("CpuTracker") {
1957            @Override
1958            public void run() {
1959                while (true) {
1960                    try {
1961                        try {
1962                            synchronized(this) {
1963                                final long now = SystemClock.uptimeMillis();
1964                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1965                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1966                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1967                                //        + ", write delay=" + nextWriteDelay);
1968                                if (nextWriteDelay < nextCpuDelay) {
1969                                    nextCpuDelay = nextWriteDelay;
1970                                }
1971                                if (nextCpuDelay > 0) {
1972                                    mProcessCpuMutexFree.set(true);
1973                                    this.wait(nextCpuDelay);
1974                                }
1975                            }
1976                        } catch (InterruptedException e) {
1977                        }
1978                        updateCpuStatsNow();
1979                    } catch (Exception e) {
1980                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1981                    }
1982                }
1983            }
1984        };
1985
1986        Watchdog.getInstance().addMonitor(this);
1987        Watchdog.getInstance().addThread(mHandler);
1988    }
1989
1990    private void start() {
1991        mProcessCpuThread.start();
1992
1993        mBatteryStatsService.publish(mContext);
1994        mUsageStatsService.publish(mContext);
1995        mAppOpsService.publish(mContext);
1996        startRunning(null, null, null, null);
1997    }
1998
1999    @Override
2000    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2001            throws RemoteException {
2002        if (code == SYSPROPS_TRANSACTION) {
2003            // We need to tell all apps about the system property change.
2004            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2005            synchronized(this) {
2006                final int NP = mProcessNames.getMap().size();
2007                for (int ip=0; ip<NP; ip++) {
2008                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2009                    final int NA = apps.size();
2010                    for (int ia=0; ia<NA; ia++) {
2011                        ProcessRecord app = apps.valueAt(ia);
2012                        if (app.thread != null) {
2013                            procs.add(app.thread.asBinder());
2014                        }
2015                    }
2016                }
2017            }
2018
2019            int N = procs.size();
2020            for (int i=0; i<N; i++) {
2021                Parcel data2 = Parcel.obtain();
2022                try {
2023                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2024                } catch (RemoteException e) {
2025                }
2026                data2.recycle();
2027            }
2028        }
2029        try {
2030            return super.onTransact(code, data, reply, flags);
2031        } catch (RuntimeException e) {
2032            // The activity manager only throws security exceptions, so let's
2033            // log all others.
2034            if (!(e instanceof SecurityException)) {
2035                Slog.wtf(TAG, "Activity Manager Crash", e);
2036            }
2037            throw e;
2038        }
2039    }
2040
2041    void updateCpuStats() {
2042        final long now = SystemClock.uptimeMillis();
2043        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2044            return;
2045        }
2046        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2047            synchronized (mProcessCpuThread) {
2048                mProcessCpuThread.notify();
2049            }
2050        }
2051    }
2052
2053    void updateCpuStatsNow() {
2054        synchronized (mProcessCpuThread) {
2055            mProcessCpuMutexFree.set(false);
2056            final long now = SystemClock.uptimeMillis();
2057            boolean haveNewCpuStats = false;
2058
2059            if (MONITOR_CPU_USAGE &&
2060                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2061                mLastCpuTime.set(now);
2062                haveNewCpuStats = true;
2063                mProcessCpuTracker.update();
2064                //Slog.i(TAG, mProcessCpu.printCurrentState());
2065                //Slog.i(TAG, "Total CPU usage: "
2066                //        + mProcessCpu.getTotalCpuPercent() + "%");
2067
2068                // Slog the cpu usage if the property is set.
2069                if ("true".equals(SystemProperties.get("events.cpu"))) {
2070                    int user = mProcessCpuTracker.getLastUserTime();
2071                    int system = mProcessCpuTracker.getLastSystemTime();
2072                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2073                    int irq = mProcessCpuTracker.getLastIrqTime();
2074                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2075                    int idle = mProcessCpuTracker.getLastIdleTime();
2076
2077                    int total = user + system + iowait + irq + softIrq + idle;
2078                    if (total == 0) total = 1;
2079
2080                    EventLog.writeEvent(EventLogTags.CPU,
2081                            ((user+system+iowait+irq+softIrq) * 100) / total,
2082                            (user * 100) / total,
2083                            (system * 100) / total,
2084                            (iowait * 100) / total,
2085                            (irq * 100) / total,
2086                            (softIrq * 100) / total);
2087                }
2088            }
2089
2090            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2091            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2092            synchronized(bstats) {
2093                synchronized(mPidsSelfLocked) {
2094                    if (haveNewCpuStats) {
2095                        if (mOnBattery) {
2096                            int perc = bstats.startAddingCpuLocked();
2097                            int totalUTime = 0;
2098                            int totalSTime = 0;
2099                            final int N = mProcessCpuTracker.countStats();
2100                            for (int i=0; i<N; i++) {
2101                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2102                                if (!st.working) {
2103                                    continue;
2104                                }
2105                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2106                                int otherUTime = (st.rel_utime*perc)/100;
2107                                int otherSTime = (st.rel_stime*perc)/100;
2108                                totalUTime += otherUTime;
2109                                totalSTime += otherSTime;
2110                                if (pr != null) {
2111                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2112                                    if (ps == null || !ps.isActive()) {
2113                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2114                                                pr.info.uid, pr.processName);
2115                                    }
2116                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2117                                            st.rel_stime-otherSTime);
2118                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2119                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2120                                } else {
2121                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2122                                    if (ps == null || !ps.isActive()) {
2123                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2124                                                bstats.mapUid(st.uid), st.name);
2125                                    }
2126                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2127                                            st.rel_stime-otherSTime);
2128                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2129                                }
2130                            }
2131                            bstats.finishAddingCpuLocked(perc, totalUTime,
2132                                    totalSTime, cpuSpeedTimes);
2133                        }
2134                    }
2135                }
2136
2137                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2138                    mLastWriteTime = now;
2139                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2140                }
2141            }
2142        }
2143    }
2144
2145    @Override
2146    public void batteryNeedsCpuUpdate() {
2147        updateCpuStatsNow();
2148    }
2149
2150    @Override
2151    public void batteryPowerChanged(boolean onBattery) {
2152        // When plugging in, update the CPU stats first before changing
2153        // the plug state.
2154        updateCpuStatsNow();
2155        synchronized (this) {
2156            synchronized(mPidsSelfLocked) {
2157                mOnBattery = DEBUG_POWER ? true : onBattery;
2158            }
2159        }
2160    }
2161
2162    /**
2163     * Initialize the application bind args. These are passed to each
2164     * process when the bindApplication() IPC is sent to the process. They're
2165     * lazily setup to make sure the services are running when they're asked for.
2166     */
2167    private HashMap<String, IBinder> getCommonServicesLocked() {
2168        if (mAppBindArgs == null) {
2169            mAppBindArgs = new HashMap<String, IBinder>();
2170
2171            // Setup the application init args
2172            mAppBindArgs.put("package", ServiceManager.getService("package"));
2173            mAppBindArgs.put("window", ServiceManager.getService("window"));
2174            mAppBindArgs.put(Context.ALARM_SERVICE,
2175                    ServiceManager.getService(Context.ALARM_SERVICE));
2176        }
2177        return mAppBindArgs;
2178    }
2179
2180    final void setFocusedActivityLocked(ActivityRecord r) {
2181        if (mFocusedActivity != r) {
2182            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2183            mFocusedActivity = r;
2184            mStackSupervisor.setFocusedStack(r);
2185            if (r != null) {
2186                mWindowManager.setFocusedApp(r.appToken, true);
2187            }
2188            applyUpdateLockStateLocked(r);
2189        }
2190    }
2191
2192    @Override
2193    public void setFocusedStack(int stackId) {
2194        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2195        synchronized (ActivityManagerService.this) {
2196            ActivityStack stack = mStackSupervisor.getStack(stackId);
2197            if (stack != null) {
2198                ActivityRecord r = stack.topRunningActivityLocked(null);
2199                if (r != null) {
2200                    setFocusedActivityLocked(r);
2201                }
2202            }
2203        }
2204    }
2205
2206    @Override
2207    public void notifyActivityDrawn(IBinder token) {
2208        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2209        synchronized (this) {
2210            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2211            if (r != null) {
2212                r.task.stack.notifyActivityDrawnLocked(r);
2213            }
2214        }
2215    }
2216
2217    final void applyUpdateLockStateLocked(ActivityRecord r) {
2218        // Modifications to the UpdateLock state are done on our handler, outside
2219        // the activity manager's locks.  The new state is determined based on the
2220        // state *now* of the relevant activity record.  The object is passed to
2221        // the handler solely for logging detail, not to be consulted/modified.
2222        final boolean nextState = r != null && r.immersive;
2223        mHandler.sendMessage(
2224                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2225    }
2226
2227    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2228        Message msg = Message.obtain();
2229        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2230        msg.obj = r.task.askedCompatMode ? null : r;
2231        mHandler.sendMessage(msg);
2232    }
2233
2234    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2235            String what, Object obj, ProcessRecord srcApp) {
2236        app.lastActivityTime = now;
2237
2238        if (app.activities.size() > 0) {
2239            // Don't want to touch dependent processes that are hosting activities.
2240            return index;
2241        }
2242
2243        int lrui = mLruProcesses.lastIndexOf(app);
2244        if (lrui < 0) {
2245            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2246                    + what + " " + obj + " from " + srcApp);
2247            return index;
2248        }
2249
2250        if (lrui >= index) {
2251            // Don't want to cause this to move dependent processes *back* in the
2252            // list as if they were less frequently used.
2253            return index;
2254        }
2255
2256        if (lrui >= mLruProcessActivityStart) {
2257            // Don't want to touch dependent processes that are hosting activities.
2258            return index;
2259        }
2260
2261        mLruProcesses.remove(lrui);
2262        if (index > 0) {
2263            index--;
2264        }
2265        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2266                + " in LRU list: " + app);
2267        mLruProcesses.add(index, app);
2268        return index;
2269    }
2270
2271    final void removeLruProcessLocked(ProcessRecord app) {
2272        int lrui = mLruProcesses.lastIndexOf(app);
2273        if (lrui >= 0) {
2274            if (lrui <= mLruProcessActivityStart) {
2275                mLruProcessActivityStart--;
2276            }
2277            if (lrui <= mLruProcessServiceStart) {
2278                mLruProcessServiceStart--;
2279            }
2280            mLruProcesses.remove(lrui);
2281        }
2282    }
2283
2284    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2285            ProcessRecord client) {
2286        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2287        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2288        if (!activityChange && hasActivity) {
2289            // The process has activties, so we are only going to allow activity-based
2290            // adjustments move it.  It should be kept in the front of the list with other
2291            // processes that have activities, and we don't want those to change their
2292            // order except due to activity operations.
2293            return;
2294        }
2295
2296        mLruSeq++;
2297        final long now = SystemClock.uptimeMillis();
2298        app.lastActivityTime = now;
2299
2300        // First a quick reject: if the app is already at the position we will
2301        // put it, then there is nothing to do.
2302        if (hasActivity) {
2303            final int N = mLruProcesses.size();
2304            if (N > 0 && mLruProcesses.get(N-1) == app) {
2305                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2306                return;
2307            }
2308        } else {
2309            if (mLruProcessServiceStart > 0
2310                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2311                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2312                return;
2313            }
2314        }
2315
2316        int lrui = mLruProcesses.lastIndexOf(app);
2317
2318        if (app.persistent && lrui >= 0) {
2319            // We don't care about the position of persistent processes, as long as
2320            // they are in the list.
2321            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2322            return;
2323        }
2324
2325        /* In progress: compute new position first, so we can avoid doing work
2326           if the process is not actually going to move.  Not yet working.
2327        int addIndex;
2328        int nextIndex;
2329        boolean inActivity = false, inService = false;
2330        if (hasActivity) {
2331            // Process has activities, put it at the very tipsy-top.
2332            addIndex = mLruProcesses.size();
2333            nextIndex = mLruProcessServiceStart;
2334            inActivity = true;
2335        } else if (hasService) {
2336            // Process has services, put it at the top of the service list.
2337            addIndex = mLruProcessActivityStart;
2338            nextIndex = mLruProcessServiceStart;
2339            inActivity = true;
2340            inService = true;
2341        } else  {
2342            // Process not otherwise of interest, it goes to the top of the non-service area.
2343            addIndex = mLruProcessServiceStart;
2344            if (client != null) {
2345                int clientIndex = mLruProcesses.lastIndexOf(client);
2346                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2347                        + app);
2348                if (clientIndex >= 0 && addIndex > clientIndex) {
2349                    addIndex = clientIndex;
2350                }
2351            }
2352            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2353        }
2354
2355        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2356                + mLruProcessActivityStart + "): " + app);
2357        */
2358
2359        if (lrui >= 0) {
2360            if (lrui < mLruProcessActivityStart) {
2361                mLruProcessActivityStart--;
2362            }
2363            if (lrui < mLruProcessServiceStart) {
2364                mLruProcessServiceStart--;
2365            }
2366            /*
2367            if (addIndex > lrui) {
2368                addIndex--;
2369            }
2370            if (nextIndex > lrui) {
2371                nextIndex--;
2372            }
2373            */
2374            mLruProcesses.remove(lrui);
2375        }
2376
2377        /*
2378        mLruProcesses.add(addIndex, app);
2379        if (inActivity) {
2380            mLruProcessActivityStart++;
2381        }
2382        if (inService) {
2383            mLruProcessActivityStart++;
2384        }
2385        */
2386
2387        int nextIndex;
2388        if (hasActivity) {
2389            final int N = mLruProcesses.size();
2390            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2391                // Process doesn't have activities, but has clients with
2392                // activities...  move it up, but one below the top (the top
2393                // should always have a real activity).
2394                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2395                mLruProcesses.add(N-1, app);
2396                // To keep it from spamming the LRU list (by making a bunch of clients),
2397                // we will push down any other entries owned by the app.
2398                final int uid = app.info.uid;
2399                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2400                    ProcessRecord subProc = mLruProcesses.get(i);
2401                    if (subProc.info.uid == uid) {
2402                        // We want to push this one down the list.  If the process after
2403                        // it is for the same uid, however, don't do so, because we don't
2404                        // want them internally to be re-ordered.
2405                        if (mLruProcesses.get(i-1).info.uid != uid) {
2406                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2407                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2408                            ProcessRecord tmp = mLruProcesses.get(i);
2409                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2410                            mLruProcesses.set(i-1, tmp);
2411                            i--;
2412                        }
2413                    } else {
2414                        // A gap, we can stop here.
2415                        break;
2416                    }
2417                }
2418            } else {
2419                // Process has activities, put it at the very tipsy-top.
2420                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2421                mLruProcesses.add(app);
2422            }
2423            nextIndex = mLruProcessServiceStart;
2424        } else if (hasService) {
2425            // Process has services, put it at the top of the service list.
2426            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2427            mLruProcesses.add(mLruProcessActivityStart, app);
2428            nextIndex = mLruProcessServiceStart;
2429            mLruProcessActivityStart++;
2430        } else  {
2431            // Process not otherwise of interest, it goes to the top of the non-service area.
2432            int index = mLruProcessServiceStart;
2433            if (client != null) {
2434                // If there is a client, don't allow the process to be moved up higher
2435                // in the list than that client.
2436                int clientIndex = mLruProcesses.lastIndexOf(client);
2437                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2438                        + " when updating " + app);
2439                if (clientIndex <= lrui) {
2440                    // Don't allow the client index restriction to push it down farther in the
2441                    // list than it already is.
2442                    clientIndex = lrui;
2443                }
2444                if (clientIndex >= 0 && index > clientIndex) {
2445                    index = clientIndex;
2446                }
2447            }
2448            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2449            mLruProcesses.add(index, app);
2450            nextIndex = index-1;
2451            mLruProcessActivityStart++;
2452            mLruProcessServiceStart++;
2453        }
2454
2455        // If the app is currently using a content provider or service,
2456        // bump those processes as well.
2457        for (int j=app.connections.size()-1; j>=0; j--) {
2458            ConnectionRecord cr = app.connections.valueAt(j);
2459            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2460                    && cr.binding.service.app != null
2461                    && cr.binding.service.app.lruSeq != mLruSeq
2462                    && !cr.binding.service.app.persistent) {
2463                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2464                        "service connection", cr, app);
2465            }
2466        }
2467        for (int j=app.conProviders.size()-1; j>=0; j--) {
2468            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2469            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2470                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2471                        "provider reference", cpr, app);
2472            }
2473        }
2474    }
2475
2476    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2477        if (uid == Process.SYSTEM_UID) {
2478            // The system gets to run in any process.  If there are multiple
2479            // processes with the same uid, just pick the first (this
2480            // should never happen).
2481            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2482            if (procs == null) return null;
2483            final int N = procs.size();
2484            for (int i = 0; i < N; i++) {
2485                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2486            }
2487        }
2488        ProcessRecord proc = mProcessNames.get(processName, uid);
2489        if (false && proc != null && !keepIfLarge
2490                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2491                && proc.lastCachedPss >= 4000) {
2492            // Turn this condition on to cause killing to happen regularly, for testing.
2493            if (proc.baseProcessTracker != null) {
2494                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2495            }
2496            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2497                    + "k from cached");
2498        } else if (proc != null && !keepIfLarge
2499                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2500                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2501            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2502            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2503                if (proc.baseProcessTracker != null) {
2504                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2505                }
2506                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2507                        + "k from cached");
2508            }
2509        }
2510        return proc;
2511    }
2512
2513    void ensurePackageDexOpt(String packageName) {
2514        IPackageManager pm = AppGlobals.getPackageManager();
2515        try {
2516            if (pm.performDexOpt(packageName)) {
2517                mDidDexOpt = true;
2518            }
2519        } catch (RemoteException e) {
2520        }
2521    }
2522
2523    boolean isNextTransitionForward() {
2524        int transit = mWindowManager.getPendingAppTransition();
2525        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2526                || transit == AppTransition.TRANSIT_TASK_OPEN
2527                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2528    }
2529
2530    final ProcessRecord startProcessLocked(String processName,
2531            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2532            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2533            boolean isolated, boolean keepIfLarge) {
2534        ProcessRecord app;
2535        if (!isolated) {
2536            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2537        } else {
2538            // If this is an isolated process, it can't re-use an existing process.
2539            app = null;
2540        }
2541        // We don't have to do anything more if:
2542        // (1) There is an existing application record; and
2543        // (2) The caller doesn't think it is dead, OR there is no thread
2544        //     object attached to it so we know it couldn't have crashed; and
2545        // (3) There is a pid assigned to it, so it is either starting or
2546        //     already running.
2547        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2548                + " app=" + app + " knownToBeDead=" + knownToBeDead
2549                + " thread=" + (app != null ? app.thread : null)
2550                + " pid=" + (app != null ? app.pid : -1));
2551        if (app != null && app.pid > 0) {
2552            if (!knownToBeDead || app.thread == null) {
2553                // We already have the app running, or are waiting for it to
2554                // come up (we have a pid but not yet its thread), so keep it.
2555                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2556                // If this is a new package in the process, add the package to the list
2557                app.addPackage(info.packageName, mProcessStats);
2558                return app;
2559            }
2560
2561            // An application record is attached to a previous process,
2562            // clean it up now.
2563            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2564            handleAppDiedLocked(app, true, true);
2565        }
2566
2567        String hostingNameStr = hostingName != null
2568                ? hostingName.flattenToShortString() : null;
2569
2570        if (!isolated) {
2571            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2572                // If we are in the background, then check to see if this process
2573                // is bad.  If so, we will just silently fail.
2574                if (mBadProcesses.get(info.processName, info.uid) != null) {
2575                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2576                            + "/" + info.processName);
2577                    return null;
2578                }
2579            } else {
2580                // When the user is explicitly starting a process, then clear its
2581                // crash count so that we won't make it bad until they see at
2582                // least one crash dialog again, and make the process good again
2583                // if it had been bad.
2584                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2585                        + "/" + info.processName);
2586                mProcessCrashTimes.remove(info.processName, info.uid);
2587                if (mBadProcesses.get(info.processName, info.uid) != null) {
2588                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2589                            UserHandle.getUserId(info.uid), info.uid,
2590                            info.processName);
2591                    mBadProcesses.remove(info.processName, info.uid);
2592                    if (app != null) {
2593                        app.bad = false;
2594                    }
2595                }
2596            }
2597        }
2598
2599        if (app == null) {
2600            app = newProcessRecordLocked(info, processName, isolated);
2601            if (app == null) {
2602                Slog.w(TAG, "Failed making new process record for "
2603                        + processName + "/" + info.uid + " isolated=" + isolated);
2604                return null;
2605            }
2606            mProcessNames.put(processName, app.uid, app);
2607            if (isolated) {
2608                mIsolatedProcesses.put(app.uid, app);
2609            }
2610        } else {
2611            // If this is a new package in the process, add the package to the list
2612            app.addPackage(info.packageName, mProcessStats);
2613        }
2614
2615        // If the system is not ready yet, then hold off on starting this
2616        // process until it is.
2617        if (!mProcessesReady
2618                && !isAllowedWhileBooting(info)
2619                && !allowWhileBooting) {
2620            if (!mProcessesOnHold.contains(app)) {
2621                mProcessesOnHold.add(app);
2622            }
2623            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2624            return app;
2625        }
2626
2627        startProcessLocked(app, hostingType, hostingNameStr);
2628        return (app.pid != 0) ? app : null;
2629    }
2630
2631    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2632        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2633    }
2634
2635    private final void startProcessLocked(ProcessRecord app,
2636            String hostingType, String hostingNameStr) {
2637        if (app.pid > 0 && app.pid != MY_PID) {
2638            synchronized (mPidsSelfLocked) {
2639                mPidsSelfLocked.remove(app.pid);
2640                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2641            }
2642            app.setPid(0);
2643        }
2644
2645        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2646                "startProcessLocked removing on hold: " + app);
2647        mProcessesOnHold.remove(app);
2648
2649        updateCpuStats();
2650
2651        try {
2652            int uid = app.uid;
2653
2654            int[] gids = null;
2655            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2656            if (!app.isolated) {
2657                int[] permGids = null;
2658                try {
2659                    final PackageManager pm = mContext.getPackageManager();
2660                    permGids = pm.getPackageGids(app.info.packageName);
2661
2662                    if (Environment.isExternalStorageEmulated()) {
2663                        if (pm.checkPermission(
2664                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2665                                app.info.packageName) == PERMISSION_GRANTED) {
2666                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2667                        } else {
2668                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2669                        }
2670                    }
2671                } catch (PackageManager.NameNotFoundException e) {
2672                    Slog.w(TAG, "Unable to retrieve gids", e);
2673                }
2674
2675                /*
2676                 * Add shared application GID so applications can share some
2677                 * resources like shared libraries
2678                 */
2679                if (permGids == null) {
2680                    gids = new int[1];
2681                } else {
2682                    gids = new int[permGids.length + 1];
2683                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2684                }
2685                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2686            }
2687            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2688                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2689                        && mTopComponent != null
2690                        && app.processName.equals(mTopComponent.getPackageName())) {
2691                    uid = 0;
2692                }
2693                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2694                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2695                    uid = 0;
2696                }
2697            }
2698            int debugFlags = 0;
2699            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2700                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2701                // Also turn on CheckJNI for debuggable apps. It's quite
2702                // awkward to turn on otherwise.
2703                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2704            }
2705            // Run the app in safe mode if its manifest requests so or the
2706            // system is booted in safe mode.
2707            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2708                Zygote.systemInSafeMode == true) {
2709                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2710            }
2711            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2712                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2713            }
2714            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2715                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2716            }
2717            if ("1".equals(SystemProperties.get("debug.assert"))) {
2718                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2719            }
2720
2721            // Start the process.  It will either succeed and return a result containing
2722            // the PID of the new process, or else throw a RuntimeException.
2723            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2724                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2725                    app.info.targetSdkVersion, app.info.seinfo, null);
2726
2727            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2728            synchronized (bs) {
2729                if (bs.isOnBattery()) {
2730                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2731                }
2732            }
2733
2734            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2735                    UserHandle.getUserId(uid), startResult.pid, uid,
2736                    app.processName, hostingType,
2737                    hostingNameStr != null ? hostingNameStr : "");
2738
2739            if (app.persistent) {
2740                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2741            }
2742
2743            StringBuilder buf = mStringBuilder;
2744            buf.setLength(0);
2745            buf.append("Start proc ");
2746            buf.append(app.processName);
2747            buf.append(" for ");
2748            buf.append(hostingType);
2749            if (hostingNameStr != null) {
2750                buf.append(" ");
2751                buf.append(hostingNameStr);
2752            }
2753            buf.append(": pid=");
2754            buf.append(startResult.pid);
2755            buf.append(" uid=");
2756            buf.append(uid);
2757            buf.append(" gids={");
2758            if (gids != null) {
2759                for (int gi=0; gi<gids.length; gi++) {
2760                    if (gi != 0) buf.append(", ");
2761                    buf.append(gids[gi]);
2762
2763                }
2764            }
2765            buf.append("}");
2766            Slog.i(TAG, buf.toString());
2767            app.setPid(startResult.pid);
2768            app.usingWrapper = startResult.usingWrapper;
2769            app.removed = false;
2770            synchronized (mPidsSelfLocked) {
2771                this.mPidsSelfLocked.put(startResult.pid, app);
2772                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2773                msg.obj = app;
2774                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2775                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2776            }
2777            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_STARTED,
2778                    app.processName, app.info.uid);
2779            if (app.isolated) {
2780                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2781            }
2782        } catch (RuntimeException e) {
2783            // XXX do better error recovery.
2784            app.setPid(0);
2785            Slog.e(TAG, "Failure starting process " + app.processName, e);
2786        }
2787    }
2788
2789    void updateUsageStats(ActivityRecord component, boolean resumed) {
2790        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2791        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2792        if (resumed) {
2793            mUsageStatsService.noteResumeComponent(component.realActivity);
2794            synchronized (stats) {
2795                stats.noteActivityResumedLocked(component.app.uid);
2796            }
2797        } else {
2798            mUsageStatsService.notePauseComponent(component.realActivity);
2799            synchronized (stats) {
2800                stats.noteActivityPausedLocked(component.app.uid);
2801            }
2802        }
2803    }
2804
2805    Intent getHomeIntent() {
2806        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2807        intent.setComponent(mTopComponent);
2808        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2809            intent.addCategory(Intent.CATEGORY_HOME);
2810        }
2811        return intent;
2812    }
2813
2814    boolean startHomeActivityLocked(int userId) {
2815        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2816                && mTopAction == null) {
2817            // We are running in factory test mode, but unable to find
2818            // the factory test app, so just sit around displaying the
2819            // error message and don't try to start anything.
2820            return false;
2821        }
2822        Intent intent = getHomeIntent();
2823        ActivityInfo aInfo =
2824            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2825        if (aInfo != null) {
2826            intent.setComponent(new ComponentName(
2827                    aInfo.applicationInfo.packageName, aInfo.name));
2828            // Don't do this if the home app is currently being
2829            // instrumented.
2830            aInfo = new ActivityInfo(aInfo);
2831            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2832            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2833                    aInfo.applicationInfo.uid, true);
2834            if (app == null || app.instrumentationClass == null) {
2835                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2836                mStackSupervisor.startHomeActivity(intent, aInfo);
2837            }
2838        }
2839
2840        return true;
2841    }
2842
2843    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2844        ActivityInfo ai = null;
2845        ComponentName comp = intent.getComponent();
2846        try {
2847            if (comp != null) {
2848                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2849            } else {
2850                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2851                        intent,
2852                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2853                            flags, userId);
2854
2855                if (info != null) {
2856                    ai = info.activityInfo;
2857                }
2858            }
2859        } catch (RemoteException e) {
2860            // ignore
2861        }
2862
2863        return ai;
2864    }
2865
2866    /**
2867     * Starts the "new version setup screen" if appropriate.
2868     */
2869    void startSetupActivityLocked() {
2870        // Only do this once per boot.
2871        if (mCheckedForSetup) {
2872            return;
2873        }
2874
2875        // We will show this screen if the current one is a different
2876        // version than the last one shown, and we are not running in
2877        // low-level factory test mode.
2878        final ContentResolver resolver = mContext.getContentResolver();
2879        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2880                Settings.Global.getInt(resolver,
2881                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2882            mCheckedForSetup = true;
2883
2884            // See if we should be showing the platform update setup UI.
2885            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2886            List<ResolveInfo> ris = sSelf.mContext.getPackageManager()
2887                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2888
2889            // We don't allow third party apps to replace this.
2890            ResolveInfo ri = null;
2891            for (int i=0; ris != null && i<ris.size(); i++) {
2892                if ((ris.get(i).activityInfo.applicationInfo.flags
2893                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2894                    ri = ris.get(i);
2895                    break;
2896                }
2897            }
2898
2899            if (ri != null) {
2900                String vers = ri.activityInfo.metaData != null
2901                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2902                        : null;
2903                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2904                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2905                            Intent.METADATA_SETUP_VERSION);
2906                }
2907                String lastVers = Settings.Secure.getString(
2908                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2909                if (vers != null && !vers.equals(lastVers)) {
2910                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2911                    intent.setComponent(new ComponentName(
2912                            ri.activityInfo.packageName, ri.activityInfo.name));
2913                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2914                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2915                }
2916            }
2917        }
2918    }
2919
2920    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2921        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2922    }
2923
2924    void enforceNotIsolatedCaller(String caller) {
2925        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2926            throw new SecurityException("Isolated process not allowed to call " + caller);
2927        }
2928    }
2929
2930    @Override
2931    public int getFrontActivityScreenCompatMode() {
2932        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2933        synchronized (this) {
2934            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2935        }
2936    }
2937
2938    @Override
2939    public void setFrontActivityScreenCompatMode(int mode) {
2940        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2941                "setFrontActivityScreenCompatMode");
2942        synchronized (this) {
2943            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2944        }
2945    }
2946
2947    @Override
2948    public int getPackageScreenCompatMode(String packageName) {
2949        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2950        synchronized (this) {
2951            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2952        }
2953    }
2954
2955    @Override
2956    public void setPackageScreenCompatMode(String packageName, int mode) {
2957        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2958                "setPackageScreenCompatMode");
2959        synchronized (this) {
2960            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2961        }
2962    }
2963
2964    @Override
2965    public boolean getPackageAskScreenCompat(String packageName) {
2966        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2967        synchronized (this) {
2968            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2969        }
2970    }
2971
2972    @Override
2973    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2974        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2975                "setPackageAskScreenCompat");
2976        synchronized (this) {
2977            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2978        }
2979    }
2980
2981    private void dispatchProcessesChanged() {
2982        int N;
2983        synchronized (this) {
2984            N = mPendingProcessChanges.size();
2985            if (mActiveProcessChanges.length < N) {
2986                mActiveProcessChanges = new ProcessChangeItem[N];
2987            }
2988            mPendingProcessChanges.toArray(mActiveProcessChanges);
2989            mAvailProcessChanges.addAll(mPendingProcessChanges);
2990            mPendingProcessChanges.clear();
2991            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2992        }
2993
2994        int i = mProcessObservers.beginBroadcast();
2995        while (i > 0) {
2996            i--;
2997            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2998            if (observer != null) {
2999                try {
3000                    for (int j=0; j<N; j++) {
3001                        ProcessChangeItem item = mActiveProcessChanges[j];
3002                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3003                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3004                                    + item.pid + " uid=" + item.uid + ": "
3005                                    + item.foregroundActivities);
3006                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3007                                    item.foregroundActivities);
3008                        }
3009                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3010                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3011                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3012                            observer.onImportanceChanged(item.pid, item.uid,
3013                                    item.importance);
3014                        }
3015                    }
3016                } catch (RemoteException e) {
3017                }
3018            }
3019        }
3020        mProcessObservers.finishBroadcast();
3021    }
3022
3023    private void dispatchProcessDied(int pid, int uid) {
3024        int i = mProcessObservers.beginBroadcast();
3025        while (i > 0) {
3026            i--;
3027            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3028            if (observer != null) {
3029                try {
3030                    observer.onProcessDied(pid, uid);
3031                } catch (RemoteException e) {
3032                }
3033            }
3034        }
3035        mProcessObservers.finishBroadcast();
3036    }
3037
3038    final void doPendingActivityLaunchesLocked(boolean doResume) {
3039        final int N = mPendingActivityLaunches.size();
3040        if (N <= 0) {
3041            return;
3042        }
3043        for (int i=0; i<N; i++) {
3044            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3045            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3046                    doResume && i == (N-1), null);
3047        }
3048        mPendingActivityLaunches.clear();
3049    }
3050
3051    @Override
3052    public final int startActivity(IApplicationThread caller, String callingPackage,
3053            Intent intent, String resolvedType, IBinder resultTo,
3054            String resultWho, int requestCode, int startFlags,
3055            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3056        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3057                resultWho, requestCode,
3058                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3059    }
3060
3061    @Override
3062    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3063            Intent intent, String resolvedType, IBinder resultTo,
3064            String resultWho, int requestCode, int startFlags,
3065            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3066        enforceNotIsolatedCaller("startActivity");
3067        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3068                false, true, "startActivity", null);
3069        // TODO: Switch to user app stacks here.
3070        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3071                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3072                null, null, options, userId, null);
3073    }
3074
3075    @Override
3076    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3077            Intent intent, String resolvedType, IBinder resultTo,
3078            String resultWho, int requestCode, int startFlags, String profileFile,
3079            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3080        enforceNotIsolatedCaller("startActivityAndWait");
3081        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3082                false, true, "startActivityAndWait", null);
3083        WaitResult res = new WaitResult();
3084        // TODO: Switch to user app stacks here.
3085        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3086                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3087                res, null, options, UserHandle.getCallingUserId(), null);
3088        return res;
3089    }
3090
3091    @Override
3092    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3093            Intent intent, String resolvedType, IBinder resultTo,
3094            String resultWho, int requestCode, int startFlags, Configuration config,
3095            Bundle options, int userId) {
3096        enforceNotIsolatedCaller("startActivityWithConfig");
3097        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3098                false, true, "startActivityWithConfig", null);
3099        // TODO: Switch to user app stacks here.
3100        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3101                resolvedType, resultTo, resultWho, requestCode, startFlags,
3102                null, null, null, config, options, userId, null);
3103        return ret;
3104    }
3105
3106    @Override
3107    public int startActivityIntentSender(IApplicationThread caller,
3108            IntentSender intent, Intent fillInIntent, String resolvedType,
3109            IBinder resultTo, String resultWho, int requestCode,
3110            int flagsMask, int flagsValues, Bundle options) {
3111        enforceNotIsolatedCaller("startActivityIntentSender");
3112        // Refuse possible leaked file descriptors
3113        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3114            throw new IllegalArgumentException("File descriptors passed in Intent");
3115        }
3116
3117        IIntentSender sender = intent.getTarget();
3118        if (!(sender instanceof PendingIntentRecord)) {
3119            throw new IllegalArgumentException("Bad PendingIntent object");
3120        }
3121
3122        PendingIntentRecord pir = (PendingIntentRecord)sender;
3123
3124        synchronized (this) {
3125            // If this is coming from the currently resumed activity, it is
3126            // effectively saying that app switches are allowed at this point.
3127            final ActivityStack stack = getFocusedStack();
3128            if (stack.mResumedActivity != null &&
3129                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3130                mAppSwitchesAllowedTime = 0;
3131            }
3132        }
3133        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3134                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
3135        return ret;
3136    }
3137
3138    @Override
3139    public boolean startNextMatchingActivity(IBinder callingActivity,
3140            Intent intent, Bundle options) {
3141        // Refuse possible leaked file descriptors
3142        if (intent != null && intent.hasFileDescriptors() == true) {
3143            throw new IllegalArgumentException("File descriptors passed in Intent");
3144        }
3145
3146        synchronized (this) {
3147            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3148            if (r == null) {
3149                ActivityOptions.abort(options);
3150                return false;
3151            }
3152            if (r.app == null || r.app.thread == null) {
3153                // The caller is not running...  d'oh!
3154                ActivityOptions.abort(options);
3155                return false;
3156            }
3157            intent = new Intent(intent);
3158            // The caller is not allowed to change the data.
3159            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3160            // And we are resetting to find the next component...
3161            intent.setComponent(null);
3162
3163            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3164
3165            ActivityInfo aInfo = null;
3166            try {
3167                List<ResolveInfo> resolves =
3168                    AppGlobals.getPackageManager().queryIntentActivities(
3169                            intent, r.resolvedType,
3170                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3171                            UserHandle.getCallingUserId());
3172
3173                // Look for the original activity in the list...
3174                final int N = resolves != null ? resolves.size() : 0;
3175                for (int i=0; i<N; i++) {
3176                    ResolveInfo rInfo = resolves.get(i);
3177                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3178                            && rInfo.activityInfo.name.equals(r.info.name)) {
3179                        // We found the current one...  the next matching is
3180                        // after it.
3181                        i++;
3182                        if (i<N) {
3183                            aInfo = resolves.get(i).activityInfo;
3184                        }
3185                        if (debug) {
3186                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3187                                    + "/" + r.info.name);
3188                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3189                                    + "/" + aInfo.name);
3190                        }
3191                        break;
3192                    }
3193                }
3194            } catch (RemoteException e) {
3195            }
3196
3197            if (aInfo == null) {
3198                // Nobody who is next!
3199                ActivityOptions.abort(options);
3200                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3201                return false;
3202            }
3203
3204            intent.setComponent(new ComponentName(
3205                    aInfo.applicationInfo.packageName, aInfo.name));
3206            intent.setFlags(intent.getFlags()&~(
3207                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3208                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3209                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3210                    Intent.FLAG_ACTIVITY_NEW_TASK));
3211
3212            // Okay now we need to start the new activity, replacing the
3213            // currently running activity.  This is a little tricky because
3214            // we want to start the new one as if the current one is finished,
3215            // but not finish the current one first so that there is no flicker.
3216            // And thus...
3217            final boolean wasFinishing = r.finishing;
3218            r.finishing = true;
3219
3220            // Propagate reply information over to the new activity.
3221            final ActivityRecord resultTo = r.resultTo;
3222            final String resultWho = r.resultWho;
3223            final int requestCode = r.requestCode;
3224            r.resultTo = null;
3225            if (resultTo != null) {
3226                resultTo.removeResultsLocked(r, resultWho, requestCode);
3227            }
3228
3229            final long origId = Binder.clearCallingIdentity();
3230            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3231                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3232                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3233                    options, false, null, null);
3234            Binder.restoreCallingIdentity(origId);
3235
3236            r.finishing = wasFinishing;
3237            if (res != ActivityManager.START_SUCCESS) {
3238                return false;
3239            }
3240            return true;
3241        }
3242    }
3243
3244    final int startActivityInPackage(int uid, String callingPackage,
3245            Intent intent, String resolvedType, IBinder resultTo,
3246            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
3247
3248        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3249                false, true, "startActivityInPackage", null);
3250
3251        // TODO: Switch to user app stacks here.
3252        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3253                resultTo, resultWho, requestCode, startFlags,
3254                null, null, null, null, options, userId, null);
3255        return ret;
3256    }
3257
3258    @Override
3259    public final int startActivities(IApplicationThread caller, String callingPackage,
3260            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3261            int userId) {
3262        enforceNotIsolatedCaller("startActivities");
3263        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3264                false, true, "startActivity", null);
3265        // TODO: Switch to user app stacks here.
3266        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3267                resolvedTypes, resultTo, options, userId);
3268        return ret;
3269    }
3270
3271    final int startActivitiesInPackage(int uid, String callingPackage,
3272            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3273            Bundle options, int userId) {
3274
3275        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3276                false, true, "startActivityInPackage", null);
3277        // TODO: Switch to user app stacks here.
3278        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3279                resultTo, options, userId);
3280        return ret;
3281    }
3282
3283    final void addRecentTaskLocked(TaskRecord task) {
3284        int N = mRecentTasks.size();
3285        // Quick case: check if the top-most recent task is the same.
3286        if (N > 0 && mRecentTasks.get(0) == task) {
3287            return;
3288        }
3289        // Remove any existing entries that are the same kind of task.
3290        for (int i=0; i<N; i++) {
3291            TaskRecord tr = mRecentTasks.get(i);
3292            if (task.userId == tr.userId
3293                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3294                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3295                tr.disposeThumbnail();
3296                mRecentTasks.remove(i);
3297                i--;
3298                N--;
3299                if (task.intent == null) {
3300                    // If the new recent task we are adding is not fully
3301                    // specified, then replace it with the existing recent task.
3302                    task = tr;
3303                }
3304            }
3305        }
3306        if (N >= MAX_RECENT_TASKS) {
3307            mRecentTasks.remove(N-1).disposeThumbnail();
3308        }
3309        mRecentTasks.add(0, task);
3310    }
3311
3312    @Override
3313    public void reportActivityFullyDrawn(IBinder token) {
3314        synchronized (this) {
3315            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3316            if (r == null) {
3317                return;
3318            }
3319            r.reportFullyDrawnLocked();
3320        }
3321    }
3322
3323    @Override
3324    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3325        synchronized (this) {
3326            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3327            if (r == null) {
3328                return;
3329            }
3330            final long origId = Binder.clearCallingIdentity();
3331            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3332            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3333                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3334            if (config != null) {
3335                r.frozenBeforeDestroy = true;
3336                if (!updateConfigurationLocked(config, r, false, false)) {
3337                    mStackSupervisor.resumeTopActivitiesLocked();
3338                }
3339            }
3340            Binder.restoreCallingIdentity(origId);
3341        }
3342    }
3343
3344    @Override
3345    public int getRequestedOrientation(IBinder token) {
3346        synchronized (this) {
3347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3348            if (r == null) {
3349                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3350            }
3351            return mWindowManager.getAppOrientation(r.appToken);
3352        }
3353    }
3354
3355    /**
3356     * This is the internal entry point for handling Activity.finish().
3357     *
3358     * @param token The Binder token referencing the Activity we want to finish.
3359     * @param resultCode Result code, if any, from this Activity.
3360     * @param resultData Result data (Intent), if any, from this Activity.
3361     *
3362     * @return Returns true if the activity successfully finished, or false if it is still running.
3363     */
3364    @Override
3365    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3366        // Refuse possible leaked file descriptors
3367        if (resultData != null && resultData.hasFileDescriptors() == true) {
3368            throw new IllegalArgumentException("File descriptors passed in Intent");
3369        }
3370
3371        synchronized(this) {
3372            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3373            if (r == null) {
3374                return true;
3375            }
3376            if (mController != null) {
3377                // Find the first activity that is not finishing.
3378                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3379                if (next != null) {
3380                    // ask watcher if this is allowed
3381                    boolean resumeOK = true;
3382                    try {
3383                        resumeOK = mController.activityResuming(next.packageName);
3384                    } catch (RemoteException e) {
3385                        mController = null;
3386                        Watchdog.getInstance().setActivityController(null);
3387                    }
3388
3389                    if (!resumeOK) {
3390                        return false;
3391                    }
3392                }
3393            }
3394            final long origId = Binder.clearCallingIdentity();
3395            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3396                    resultData, "app-request", true);
3397            Binder.restoreCallingIdentity(origId);
3398            return res;
3399        }
3400    }
3401
3402    @Override
3403    public final void finishHeavyWeightApp() {
3404        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3405                != PackageManager.PERMISSION_GRANTED) {
3406            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3407                    + Binder.getCallingPid()
3408                    + ", uid=" + Binder.getCallingUid()
3409                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3410            Slog.w(TAG, msg);
3411            throw new SecurityException(msg);
3412        }
3413
3414        synchronized(this) {
3415            if (mHeavyWeightProcess == null) {
3416                return;
3417            }
3418
3419            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3420                    mHeavyWeightProcess.activities);
3421            for (int i=0; i<activities.size(); i++) {
3422                ActivityRecord r = activities.get(i);
3423                if (!r.finishing) {
3424                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3425                            null, "finish-heavy", true);
3426                }
3427            }
3428
3429            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3430                    mHeavyWeightProcess.userId, 0));
3431            mHeavyWeightProcess = null;
3432        }
3433    }
3434
3435    @Override
3436    public void crashApplication(int uid, int initialPid, String packageName,
3437            String message) {
3438        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3439                != PackageManager.PERMISSION_GRANTED) {
3440            String msg = "Permission Denial: crashApplication() from pid="
3441                    + Binder.getCallingPid()
3442                    + ", uid=" + Binder.getCallingUid()
3443                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3444            Slog.w(TAG, msg);
3445            throw new SecurityException(msg);
3446        }
3447
3448        synchronized(this) {
3449            ProcessRecord proc = null;
3450
3451            // Figure out which process to kill.  We don't trust that initialPid
3452            // still has any relation to current pids, so must scan through the
3453            // list.
3454            synchronized (mPidsSelfLocked) {
3455                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3456                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3457                    if (p.uid != uid) {
3458                        continue;
3459                    }
3460                    if (p.pid == initialPid) {
3461                        proc = p;
3462                        break;
3463                    }
3464                    if (p.pkgList.containsKey(packageName)) {
3465                        proc = p;
3466                    }
3467                }
3468            }
3469
3470            if (proc == null) {
3471                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3472                        + " initialPid=" + initialPid
3473                        + " packageName=" + packageName);
3474                return;
3475            }
3476
3477            if (proc.thread != null) {
3478                if (proc.pid == Process.myPid()) {
3479                    Log.w(TAG, "crashApplication: trying to crash self!");
3480                    return;
3481                }
3482                long ident = Binder.clearCallingIdentity();
3483                try {
3484                    proc.thread.scheduleCrash(message);
3485                } catch (RemoteException e) {
3486                }
3487                Binder.restoreCallingIdentity(ident);
3488            }
3489        }
3490    }
3491
3492    @Override
3493    public final void finishSubActivity(IBinder token, String resultWho,
3494            int requestCode) {
3495        synchronized(this) {
3496            final long origId = Binder.clearCallingIdentity();
3497            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3498            if (r != null) {
3499                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3500            }
3501            Binder.restoreCallingIdentity(origId);
3502        }
3503    }
3504
3505    @Override
3506    public boolean finishActivityAffinity(IBinder token) {
3507        synchronized(this) {
3508            final long origId = Binder.clearCallingIdentity();
3509            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3510            boolean res = false;
3511            if (r != null) {
3512                res = r.task.stack.finishActivityAffinityLocked(r);
3513            }
3514            Binder.restoreCallingIdentity(origId);
3515            return res;
3516        }
3517    }
3518
3519    @Override
3520    public boolean willActivityBeVisible(IBinder token) {
3521        synchronized(this) {
3522            ActivityStack stack = ActivityRecord.getStackLocked(token);
3523            if (stack != null) {
3524                return stack.willActivityBeVisibleLocked(token);
3525            }
3526            return false;
3527        }
3528    }
3529
3530    @Override
3531    public void overridePendingTransition(IBinder token, String packageName,
3532            int enterAnim, int exitAnim) {
3533        synchronized(this) {
3534            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3535            if (self == null) {
3536                return;
3537            }
3538
3539            final long origId = Binder.clearCallingIdentity();
3540
3541            if (self.state == ActivityState.RESUMED
3542                    || self.state == ActivityState.PAUSING) {
3543                mWindowManager.overridePendingAppTransition(packageName,
3544                        enterAnim, exitAnim, null);
3545            }
3546
3547            Binder.restoreCallingIdentity(origId);
3548        }
3549    }
3550
3551    /**
3552     * Main function for removing an existing process from the activity manager
3553     * as a result of that process going away.  Clears out all connections
3554     * to the process.
3555     */
3556    private final void handleAppDiedLocked(ProcessRecord app,
3557            boolean restarting, boolean allowRestart) {
3558        int pid = app.pid;
3559        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3560        if (!restarting) {
3561            removeLruProcessLocked(app);
3562            if (pid > 0) {
3563                ProcessList.remove(pid);
3564            }
3565        }
3566
3567        if (mProfileProc == app) {
3568            clearProfilerLocked();
3569        }
3570
3571        // Remove this application's activities from active lists.
3572        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3573
3574        app.activities.clear();
3575
3576        if (app.instrumentationClass != null) {
3577            Slog.w(TAG, "Crash of app " + app.processName
3578                  + " running instrumentation " + app.instrumentationClass);
3579            Bundle info = new Bundle();
3580            info.putString("shortMsg", "Process crashed.");
3581            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3582        }
3583
3584        if (!restarting) {
3585            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3586                // If there was nothing to resume, and we are not already
3587                // restarting this process, but there is a visible activity that
3588                // is hosted by the process...  then make sure all visible
3589                // activities are running, taking care of restarting this
3590                // process.
3591                if (hasVisibleActivities) {
3592                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3593                }
3594            }
3595        }
3596    }
3597
3598    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3599        IBinder threadBinder = thread.asBinder();
3600        // Find the application record.
3601        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3602            ProcessRecord rec = mLruProcesses.get(i);
3603            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3604                return i;
3605            }
3606        }
3607        return -1;
3608    }
3609
3610    final ProcessRecord getRecordForAppLocked(
3611            IApplicationThread thread) {
3612        if (thread == null) {
3613            return null;
3614        }
3615
3616        int appIndex = getLRURecordIndexForAppLocked(thread);
3617        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3618    }
3619
3620    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3621        // If there are no longer any background processes running,
3622        // and the app that died was not running instrumentation,
3623        // then tell everyone we are now low on memory.
3624        boolean haveBg = false;
3625        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3626            ProcessRecord rec = mLruProcesses.get(i);
3627            if (rec.thread != null
3628                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3629                haveBg = true;
3630                break;
3631            }
3632        }
3633
3634        if (!haveBg) {
3635            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3636            if (doReport) {
3637                long now = SystemClock.uptimeMillis();
3638                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3639                    doReport = false;
3640                } else {
3641                    mLastMemUsageReportTime = now;
3642                }
3643            }
3644            final ArrayList<ProcessMemInfo> memInfos
3645                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3646            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3647            long now = SystemClock.uptimeMillis();
3648            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3649                ProcessRecord rec = mLruProcesses.get(i);
3650                if (rec == dyingProc || rec.thread == null) {
3651                    continue;
3652                }
3653                if (doReport) {
3654                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3655                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3656                }
3657                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3658                    // The low memory report is overriding any current
3659                    // state for a GC request.  Make sure to do
3660                    // heavy/important/visible/foreground processes first.
3661                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3662                        rec.lastRequestedGc = 0;
3663                    } else {
3664                        rec.lastRequestedGc = rec.lastLowMemory;
3665                    }
3666                    rec.reportLowMemory = true;
3667                    rec.lastLowMemory = now;
3668                    mProcessesToGc.remove(rec);
3669                    addProcessToGcListLocked(rec);
3670                }
3671            }
3672            if (doReport) {
3673                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3674                mHandler.sendMessage(msg);
3675            }
3676            scheduleAppGcsLocked();
3677        }
3678    }
3679
3680    final void appDiedLocked(ProcessRecord app, int pid,
3681            IApplicationThread thread) {
3682
3683        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3684        synchronized (stats) {
3685            stats.noteProcessDiedLocked(app.info.uid, pid);
3686        }
3687
3688        // Clean up already done if the process has been re-started.
3689        if (app.pid == pid && app.thread != null &&
3690                app.thread.asBinder() == thread.asBinder()) {
3691            boolean doLowMem = app.instrumentationClass == null;
3692            boolean doOomAdj = doLowMem;
3693            if (!app.killedByAm) {
3694                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3695                        + ") has died.");
3696                mAllowLowerMemLevel = true;
3697            } else {
3698                // Note that we always want to do oom adj to update our state with the
3699                // new number of procs.
3700                mAllowLowerMemLevel = false;
3701                doLowMem = false;
3702            }
3703            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3704            if (DEBUG_CLEANUP) Slog.v(
3705                TAG, "Dying app: " + app + ", pid: " + pid
3706                + ", thread: " + thread.asBinder());
3707            handleAppDiedLocked(app, false, true);
3708
3709            if (doOomAdj) {
3710                updateOomAdjLocked();
3711            }
3712            if (doLowMem) {
3713                doLowMemReportIfNeededLocked(app);
3714            }
3715        } else if (app.pid != pid) {
3716            // A new process has already been started.
3717            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3718                    + ") has died and restarted (pid " + app.pid + ").");
3719            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3720        } else if (DEBUG_PROCESSES) {
3721            Slog.d(TAG, "Received spurious death notification for thread "
3722                    + thread.asBinder());
3723        }
3724    }
3725
3726    /**
3727     * If a stack trace dump file is configured, dump process stack traces.
3728     * @param clearTraces causes the dump file to be erased prior to the new
3729     *    traces being written, if true; when false, the new traces will be
3730     *    appended to any existing file content.
3731     * @param firstPids of dalvik VM processes to dump stack traces for first
3732     * @param lastPids of dalvik VM processes to dump stack traces for last
3733     * @param nativeProcs optional list of native process names to dump stack crawls
3734     * @return file containing stack traces, or null if no dump file is configured
3735     */
3736    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3737            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3738        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3739        if (tracesPath == null || tracesPath.length() == 0) {
3740            return null;
3741        }
3742
3743        File tracesFile = new File(tracesPath);
3744        try {
3745            File tracesDir = tracesFile.getParentFile();
3746            if (!tracesDir.exists()) {
3747                tracesFile.mkdirs();
3748                if (!SELinux.restorecon(tracesDir)) {
3749                    return null;
3750                }
3751            }
3752            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3753
3754            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3755            tracesFile.createNewFile();
3756            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3757        } catch (IOException e) {
3758            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3759            return null;
3760        }
3761
3762        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3763        return tracesFile;
3764    }
3765
3766    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3767            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3768        // Use a FileObserver to detect when traces finish writing.
3769        // The order of traces is considered important to maintain for legibility.
3770        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3771            @Override
3772            public synchronized void onEvent(int event, String path) { notify(); }
3773        };
3774
3775        try {
3776            observer.startWatching();
3777
3778            // First collect all of the stacks of the most important pids.
3779            if (firstPids != null) {
3780                try {
3781                    int num = firstPids.size();
3782                    for (int i = 0; i < num; i++) {
3783                        synchronized (observer) {
3784                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3785                            observer.wait(200);  // Wait for write-close, give up after 200msec
3786                        }
3787                    }
3788                } catch (InterruptedException e) {
3789                    Log.wtf(TAG, e);
3790                }
3791            }
3792
3793            // Next collect the stacks of the native pids
3794            if (nativeProcs != null) {
3795                int[] pids = Process.getPidsForCommands(nativeProcs);
3796                if (pids != null) {
3797                    for (int pid : pids) {
3798                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3799                    }
3800                }
3801            }
3802
3803            // Lastly, measure CPU usage.
3804            if (processCpuTracker != null) {
3805                processCpuTracker.init();
3806                System.gc();
3807                processCpuTracker.update();
3808                try {
3809                    synchronized (processCpuTracker) {
3810                        processCpuTracker.wait(500); // measure over 1/2 second.
3811                    }
3812                } catch (InterruptedException e) {
3813                }
3814                processCpuTracker.update();
3815
3816                // We'll take the stack crawls of just the top apps using CPU.
3817                final int N = processCpuTracker.countWorkingStats();
3818                int numProcs = 0;
3819                for (int i=0; i<N && numProcs<5; i++) {
3820                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3821                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3822                        numProcs++;
3823                        try {
3824                            synchronized (observer) {
3825                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3826                                observer.wait(200);  // Wait for write-close, give up after 200msec
3827                            }
3828                        } catch (InterruptedException e) {
3829                            Log.wtf(TAG, e);
3830                        }
3831
3832                    }
3833                }
3834            }
3835        } finally {
3836            observer.stopWatching();
3837        }
3838    }
3839
3840    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3841        if (true || IS_USER_BUILD) {
3842            return;
3843        }
3844        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3845        if (tracesPath == null || tracesPath.length() == 0) {
3846            return;
3847        }
3848
3849        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3850        StrictMode.allowThreadDiskWrites();
3851        try {
3852            final File tracesFile = new File(tracesPath);
3853            final File tracesDir = tracesFile.getParentFile();
3854            final File tracesTmp = new File(tracesDir, "__tmp__");
3855            try {
3856                if (!tracesDir.exists()) {
3857                    tracesFile.mkdirs();
3858                    if (!SELinux.restorecon(tracesDir.getPath())) {
3859                        return;
3860                    }
3861                }
3862                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3863
3864                if (tracesFile.exists()) {
3865                    tracesTmp.delete();
3866                    tracesFile.renameTo(tracesTmp);
3867                }
3868                StringBuilder sb = new StringBuilder();
3869                Time tobj = new Time();
3870                tobj.set(System.currentTimeMillis());
3871                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3872                sb.append(": ");
3873                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3874                sb.append(" since ");
3875                sb.append(msg);
3876                FileOutputStream fos = new FileOutputStream(tracesFile);
3877                fos.write(sb.toString().getBytes());
3878                if (app == null) {
3879                    fos.write("\n*** No application process!".getBytes());
3880                }
3881                fos.close();
3882                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3883            } catch (IOException e) {
3884                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3885                return;
3886            }
3887
3888            if (app != null) {
3889                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3890                firstPids.add(app.pid);
3891                dumpStackTraces(tracesPath, firstPids, null, null, null);
3892            }
3893
3894            File lastTracesFile = null;
3895            File curTracesFile = null;
3896            for (int i=9; i>=0; i--) {
3897                String name = String.format(Locale.US, "slow%02d.txt", i);
3898                curTracesFile = new File(tracesDir, name);
3899                if (curTracesFile.exists()) {
3900                    if (lastTracesFile != null) {
3901                        curTracesFile.renameTo(lastTracesFile);
3902                    } else {
3903                        curTracesFile.delete();
3904                    }
3905                }
3906                lastTracesFile = curTracesFile;
3907            }
3908            tracesFile.renameTo(curTracesFile);
3909            if (tracesTmp.exists()) {
3910                tracesTmp.renameTo(tracesFile);
3911            }
3912        } finally {
3913            StrictMode.setThreadPolicy(oldPolicy);
3914        }
3915    }
3916
3917    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3918            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3919        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3920        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3921
3922        if (mController != null) {
3923            try {
3924                // 0 == continue, -1 = kill process immediately
3925                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3926                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3927            } catch (RemoteException e) {
3928                mController = null;
3929                Watchdog.getInstance().setActivityController(null);
3930            }
3931        }
3932
3933        long anrTime = SystemClock.uptimeMillis();
3934        if (MONITOR_CPU_USAGE) {
3935            updateCpuStatsNow();
3936        }
3937
3938        synchronized (this) {
3939            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3940            if (mShuttingDown) {
3941                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3942                return;
3943            } else if (app.notResponding) {
3944                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3945                return;
3946            } else if (app.crashing) {
3947                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3948                return;
3949            }
3950
3951            // In case we come through here for the same app before completing
3952            // this one, mark as anring now so we will bail out.
3953            app.notResponding = true;
3954
3955            // Log the ANR to the event log.
3956            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3957                    app.processName, app.info.flags, annotation);
3958
3959            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3960            firstPids.add(app.pid);
3961
3962            int parentPid = app.pid;
3963            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3964            if (parentPid != app.pid) firstPids.add(parentPid);
3965
3966            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3967
3968            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3969                ProcessRecord r = mLruProcesses.get(i);
3970                if (r != null && r.thread != null) {
3971                    int pid = r.pid;
3972                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3973                        if (r.persistent) {
3974                            firstPids.add(pid);
3975                        } else {
3976                            lastPids.put(pid, Boolean.TRUE);
3977                        }
3978                    }
3979                }
3980            }
3981        }
3982
3983        // Log the ANR to the main log.
3984        StringBuilder info = new StringBuilder();
3985        info.setLength(0);
3986        info.append("ANR in ").append(app.processName);
3987        if (activity != null && activity.shortComponentName != null) {
3988            info.append(" (").append(activity.shortComponentName).append(")");
3989        }
3990        info.append("\n");
3991        info.append("PID: ").append(app.pid).append("\n");
3992        if (annotation != null) {
3993            info.append("Reason: ").append(annotation).append("\n");
3994        }
3995        if (parent != null && parent != activity) {
3996            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3997        }
3998
3999        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4000
4001        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4002                NATIVE_STACKS_OF_INTEREST);
4003
4004        String cpuInfo = null;
4005        if (MONITOR_CPU_USAGE) {
4006            updateCpuStatsNow();
4007            synchronized (mProcessCpuThread) {
4008                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4009            }
4010            info.append(processCpuTracker.printCurrentLoad());
4011            info.append(cpuInfo);
4012        }
4013
4014        info.append(processCpuTracker.printCurrentState(anrTime));
4015
4016        Slog.e(TAG, info.toString());
4017        if (tracesFile == null) {
4018            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4019            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4020        }
4021
4022        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4023                cpuInfo, tracesFile, null);
4024
4025        if (mController != null) {
4026            try {
4027                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4028                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4029                if (res != 0) {
4030                    if (res < 0 && app.pid != MY_PID) {
4031                        Process.killProcess(app.pid);
4032                    } else {
4033                        synchronized (this) {
4034                            mServices.scheduleServiceTimeoutLocked(app);
4035                        }
4036                    }
4037                    return;
4038                }
4039            } catch (RemoteException e) {
4040                mController = null;
4041                Watchdog.getInstance().setActivityController(null);
4042            }
4043        }
4044
4045        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4046        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4047                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4048
4049        synchronized (this) {
4050            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4051                killUnneededProcessLocked(app, "background ANR");
4052                return;
4053            }
4054
4055            // Set the app's notResponding state, and look up the errorReportReceiver
4056            makeAppNotRespondingLocked(app,
4057                    activity != null ? activity.shortComponentName : null,
4058                    annotation != null ? "ANR " + annotation : "ANR",
4059                    info.toString());
4060
4061            // Bring up the infamous App Not Responding dialog
4062            Message msg = Message.obtain();
4063            HashMap<String, Object> map = new HashMap<String, Object>();
4064            msg.what = SHOW_NOT_RESPONDING_MSG;
4065            msg.obj = map;
4066            msg.arg1 = aboveSystem ? 1 : 0;
4067            map.put("app", app);
4068            if (activity != null) {
4069                map.put("activity", activity);
4070            }
4071
4072            mHandler.sendMessage(msg);
4073        }
4074    }
4075
4076    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4077        if (!mLaunchWarningShown) {
4078            mLaunchWarningShown = true;
4079            mHandler.post(new Runnable() {
4080                @Override
4081                public void run() {
4082                    synchronized (ActivityManagerService.this) {
4083                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4084                        d.show();
4085                        mHandler.postDelayed(new Runnable() {
4086                            @Override
4087                            public void run() {
4088                                synchronized (ActivityManagerService.this) {
4089                                    d.dismiss();
4090                                    mLaunchWarningShown = false;
4091                                }
4092                            }
4093                        }, 4000);
4094                    }
4095                }
4096            });
4097        }
4098    }
4099
4100    @Override
4101    public boolean clearApplicationUserData(final String packageName,
4102            final IPackageDataObserver observer, int userId) {
4103        enforceNotIsolatedCaller("clearApplicationUserData");
4104        int uid = Binder.getCallingUid();
4105        int pid = Binder.getCallingPid();
4106        userId = handleIncomingUser(pid, uid,
4107                userId, false, true, "clearApplicationUserData", null);
4108        long callingId = Binder.clearCallingIdentity();
4109        try {
4110            IPackageManager pm = AppGlobals.getPackageManager();
4111            int pkgUid = -1;
4112            synchronized(this) {
4113                try {
4114                    pkgUid = pm.getPackageUid(packageName, userId);
4115                } catch (RemoteException e) {
4116                }
4117                if (pkgUid == -1) {
4118                    Slog.w(TAG, "Invalid packageName: " + packageName);
4119                    if (observer != null) {
4120                        try {
4121                            observer.onRemoveCompleted(packageName, false);
4122                        } catch (RemoteException e) {
4123                            Slog.i(TAG, "Observer no longer exists.");
4124                        }
4125                    }
4126                    return false;
4127                }
4128                if (uid == pkgUid || checkComponentPermission(
4129                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4130                        pid, uid, -1, true)
4131                        == PackageManager.PERMISSION_GRANTED) {
4132                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4133                } else {
4134                    throw new SecurityException("PID " + pid + " does not have permission "
4135                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4136                                    + " of package " + packageName);
4137                }
4138            }
4139
4140            try {
4141                // Clear application user data
4142                pm.clearApplicationUserData(packageName, observer, userId);
4143
4144                // Remove all permissions granted from/to this package
4145                removeUriPermissionsForPackageLocked(packageName, userId, true);
4146
4147                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4148                        Uri.fromParts("package", packageName, null));
4149                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4150                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4151                        null, null, 0, null, null, null, false, false, userId);
4152            } catch (RemoteException e) {
4153            }
4154        } finally {
4155            Binder.restoreCallingIdentity(callingId);
4156        }
4157        return true;
4158    }
4159
4160    @Override
4161    public void killBackgroundProcesses(final String packageName, int userId) {
4162        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4163                != PackageManager.PERMISSION_GRANTED &&
4164                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4165                        != PackageManager.PERMISSION_GRANTED) {
4166            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4167                    + Binder.getCallingPid()
4168                    + ", uid=" + Binder.getCallingUid()
4169                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4170            Slog.w(TAG, msg);
4171            throw new SecurityException(msg);
4172        }
4173
4174        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4175                userId, true, true, "killBackgroundProcesses", null);
4176        long callingId = Binder.clearCallingIdentity();
4177        try {
4178            IPackageManager pm = AppGlobals.getPackageManager();
4179            synchronized(this) {
4180                int appId = -1;
4181                try {
4182                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4183                } catch (RemoteException e) {
4184                }
4185                if (appId == -1) {
4186                    Slog.w(TAG, "Invalid packageName: " + packageName);
4187                    return;
4188                }
4189                killPackageProcessesLocked(packageName, appId, userId,
4190                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4191            }
4192        } finally {
4193            Binder.restoreCallingIdentity(callingId);
4194        }
4195    }
4196
4197    @Override
4198    public void killAllBackgroundProcesses() {
4199        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4200                != PackageManager.PERMISSION_GRANTED) {
4201            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4202                    + Binder.getCallingPid()
4203                    + ", uid=" + Binder.getCallingUid()
4204                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4205            Slog.w(TAG, msg);
4206            throw new SecurityException(msg);
4207        }
4208
4209        long callingId = Binder.clearCallingIdentity();
4210        try {
4211            synchronized(this) {
4212                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4213                final int NP = mProcessNames.getMap().size();
4214                for (int ip=0; ip<NP; ip++) {
4215                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4216                    final int NA = apps.size();
4217                    for (int ia=0; ia<NA; ia++) {
4218                        ProcessRecord app = apps.valueAt(ia);
4219                        if (app.persistent) {
4220                            // we don't kill persistent processes
4221                            continue;
4222                        }
4223                        if (app.removed) {
4224                            procs.add(app);
4225                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4226                            app.removed = true;
4227                            procs.add(app);
4228                        }
4229                    }
4230                }
4231
4232                int N = procs.size();
4233                for (int i=0; i<N; i++) {
4234                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4235                }
4236                mAllowLowerMemLevel = true;
4237                updateOomAdjLocked();
4238                doLowMemReportIfNeededLocked(null);
4239            }
4240        } finally {
4241            Binder.restoreCallingIdentity(callingId);
4242        }
4243    }
4244
4245    @Override
4246    public void forceStopPackage(final String packageName, int userId) {
4247        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4248                != PackageManager.PERMISSION_GRANTED) {
4249            String msg = "Permission Denial: forceStopPackage() from pid="
4250                    + Binder.getCallingPid()
4251                    + ", uid=" + Binder.getCallingUid()
4252                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4253            Slog.w(TAG, msg);
4254            throw new SecurityException(msg);
4255        }
4256        final int callingPid = Binder.getCallingPid();
4257        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4258                userId, true, true, "forceStopPackage", null);
4259        long callingId = Binder.clearCallingIdentity();
4260        try {
4261            IPackageManager pm = AppGlobals.getPackageManager();
4262            synchronized(this) {
4263                int[] users = userId == UserHandle.USER_ALL
4264                        ? getUsersLocked() : new int[] { userId };
4265                for (int user : users) {
4266                    int pkgUid = -1;
4267                    try {
4268                        pkgUid = pm.getPackageUid(packageName, user);
4269                    } catch (RemoteException e) {
4270                    }
4271                    if (pkgUid == -1) {
4272                        Slog.w(TAG, "Invalid packageName: " + packageName);
4273                        continue;
4274                    }
4275                    try {
4276                        pm.setPackageStoppedState(packageName, true, user);
4277                    } catch (RemoteException e) {
4278                    } catch (IllegalArgumentException e) {
4279                        Slog.w(TAG, "Failed trying to unstop package "
4280                                + packageName + ": " + e);
4281                    }
4282                    if (isUserRunningLocked(user, false)) {
4283                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4284                    }
4285                }
4286            }
4287        } finally {
4288            Binder.restoreCallingIdentity(callingId);
4289        }
4290    }
4291
4292    /*
4293     * The pkg name and app id have to be specified.
4294     */
4295    @Override
4296    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4297        if (pkg == null) {
4298            return;
4299        }
4300        // Make sure the uid is valid.
4301        if (appid < 0) {
4302            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4303            return;
4304        }
4305        int callerUid = Binder.getCallingUid();
4306        // Only the system server can kill an application
4307        if (callerUid == Process.SYSTEM_UID) {
4308            // Post an aysnc message to kill the application
4309            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4310            msg.arg1 = appid;
4311            msg.arg2 = 0;
4312            Bundle bundle = new Bundle();
4313            bundle.putString("pkg", pkg);
4314            bundle.putString("reason", reason);
4315            msg.obj = bundle;
4316            mHandler.sendMessage(msg);
4317        } else {
4318            throw new SecurityException(callerUid + " cannot kill pkg: " +
4319                    pkg);
4320        }
4321    }
4322
4323    @Override
4324    public void closeSystemDialogs(String reason) {
4325        enforceNotIsolatedCaller("closeSystemDialogs");
4326
4327        final int pid = Binder.getCallingPid();
4328        final int uid = Binder.getCallingUid();
4329        final long origId = Binder.clearCallingIdentity();
4330        try {
4331            synchronized (this) {
4332                // Only allow this from foreground processes, so that background
4333                // applications can't abuse it to prevent system UI from being shown.
4334                if (uid >= Process.FIRST_APPLICATION_UID) {
4335                    ProcessRecord proc;
4336                    synchronized (mPidsSelfLocked) {
4337                        proc = mPidsSelfLocked.get(pid);
4338                    }
4339                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4340                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4341                                + " from background process " + proc);
4342                        return;
4343                    }
4344                }
4345                closeSystemDialogsLocked(reason);
4346            }
4347        } finally {
4348            Binder.restoreCallingIdentity(origId);
4349        }
4350    }
4351
4352    void closeSystemDialogsLocked(String reason) {
4353        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4354        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4355                | Intent.FLAG_RECEIVER_FOREGROUND);
4356        if (reason != null) {
4357            intent.putExtra("reason", reason);
4358        }
4359        mWindowManager.closeSystemDialogs(reason);
4360
4361        mStackSupervisor.closeSystemDialogsLocked();
4362
4363        broadcastIntentLocked(null, null, intent, null,
4364                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4365                Process.SYSTEM_UID, UserHandle.USER_ALL);
4366    }
4367
4368    @Override
4369    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4370        enforceNotIsolatedCaller("getProcessMemoryInfo");
4371        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4372        for (int i=pids.length-1; i>=0; i--) {
4373            ProcessRecord proc;
4374            int oomAdj;
4375            synchronized (this) {
4376                synchronized (mPidsSelfLocked) {
4377                    proc = mPidsSelfLocked.get(pids[i]);
4378                    oomAdj = proc != null ? proc.setAdj : 0;
4379                }
4380            }
4381            infos[i] = new Debug.MemoryInfo();
4382            Debug.getMemoryInfo(pids[i], infos[i]);
4383            if (proc != null) {
4384                synchronized (this) {
4385                    if (proc.thread != null && proc.setAdj == oomAdj) {
4386                        // Record this for posterity if the process has been stable.
4387                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4388                                infos[i].getTotalUss(), false, proc.pkgList);
4389                    }
4390                }
4391            }
4392        }
4393        return infos;
4394    }
4395
4396    @Override
4397    public long[] getProcessPss(int[] pids) {
4398        enforceNotIsolatedCaller("getProcessPss");
4399        long[] pss = new long[pids.length];
4400        for (int i=pids.length-1; i>=0; i--) {
4401            ProcessRecord proc;
4402            int oomAdj;
4403            synchronized (this) {
4404                synchronized (mPidsSelfLocked) {
4405                    proc = mPidsSelfLocked.get(pids[i]);
4406                    oomAdj = proc != null ? proc.setAdj : 0;
4407                }
4408            }
4409            long[] tmpUss = new long[1];
4410            pss[i] = Debug.getPss(pids[i], tmpUss);
4411            if (proc != null) {
4412                synchronized (this) {
4413                    if (proc.thread != null && proc.setAdj == oomAdj) {
4414                        // Record this for posterity if the process has been stable.
4415                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4416                    }
4417                }
4418            }
4419        }
4420        return pss;
4421    }
4422
4423    @Override
4424    public void killApplicationProcess(String processName, int uid) {
4425        if (processName == null) {
4426            return;
4427        }
4428
4429        int callerUid = Binder.getCallingUid();
4430        // Only the system server can kill an application
4431        if (callerUid == Process.SYSTEM_UID) {
4432            synchronized (this) {
4433                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4434                if (app != null && app.thread != null) {
4435                    try {
4436                        app.thread.scheduleSuicide();
4437                    } catch (RemoteException e) {
4438                        // If the other end already died, then our work here is done.
4439                    }
4440                } else {
4441                    Slog.w(TAG, "Process/uid not found attempting kill of "
4442                            + processName + " / " + uid);
4443                }
4444            }
4445        } else {
4446            throw new SecurityException(callerUid + " cannot kill app process: " +
4447                    processName);
4448        }
4449    }
4450
4451    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4452        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4453                false, true, false, false, UserHandle.getUserId(uid), reason);
4454        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4455                Uri.fromParts("package", packageName, null));
4456        if (!mProcessesReady) {
4457            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4458                    | Intent.FLAG_RECEIVER_FOREGROUND);
4459        }
4460        intent.putExtra(Intent.EXTRA_UID, uid);
4461        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4462        broadcastIntentLocked(null, null, intent,
4463                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4464                false, false,
4465                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4466    }
4467
4468    private void forceStopUserLocked(int userId, String reason) {
4469        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4470        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4471        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4472                | Intent.FLAG_RECEIVER_FOREGROUND);
4473        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4474        broadcastIntentLocked(null, null, intent,
4475                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4476                false, false,
4477                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4478    }
4479
4480    private final boolean killPackageProcessesLocked(String packageName, int appId,
4481            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4482            boolean doit, boolean evenPersistent, String reason) {
4483        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4484
4485        // Remove all processes this package may have touched: all with the
4486        // same UID (except for the system or root user), and all whose name
4487        // matches the package name.
4488        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4489        final int NP = mProcessNames.getMap().size();
4490        for (int ip=0; ip<NP; ip++) {
4491            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4492            final int NA = apps.size();
4493            for (int ia=0; ia<NA; ia++) {
4494                ProcessRecord app = apps.valueAt(ia);
4495                if (app.persistent && !evenPersistent) {
4496                    // we don't kill persistent processes
4497                    continue;
4498                }
4499                if (app.removed) {
4500                    if (doit) {
4501                        procs.add(app);
4502                    }
4503                    continue;
4504                }
4505
4506                // Skip process if it doesn't meet our oom adj requirement.
4507                if (app.setAdj < minOomAdj) {
4508                    continue;
4509                }
4510
4511                // If no package is specified, we call all processes under the
4512                // give user id.
4513                if (packageName == null) {
4514                    if (app.userId != userId) {
4515                        continue;
4516                    }
4517                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4518                        continue;
4519                    }
4520                // Package has been specified, we want to hit all processes
4521                // that match it.  We need to qualify this by the processes
4522                // that are running under the specified app and user ID.
4523                } else {
4524                    if (UserHandle.getAppId(app.uid) != appId) {
4525                        continue;
4526                    }
4527                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4528                        continue;
4529                    }
4530                    if (!app.pkgList.containsKey(packageName)) {
4531                        continue;
4532                    }
4533                }
4534
4535                // Process has passed all conditions, kill it!
4536                if (!doit) {
4537                    return true;
4538                }
4539                app.removed = true;
4540                procs.add(app);
4541            }
4542        }
4543
4544        int N = procs.size();
4545        for (int i=0; i<N; i++) {
4546            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4547        }
4548        updateOomAdjLocked();
4549        return N > 0;
4550    }
4551
4552    private final boolean forceStopPackageLocked(String name, int appId,
4553            boolean callerWillRestart, boolean purgeCache, boolean doit,
4554            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4555        int i;
4556        int N;
4557
4558        if (userId == UserHandle.USER_ALL && name == null) {
4559            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4560        }
4561
4562        if (appId < 0 && name != null) {
4563            try {
4564                appId = UserHandle.getAppId(
4565                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4566            } catch (RemoteException e) {
4567            }
4568        }
4569
4570        if (doit) {
4571            if (name != null) {
4572                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4573                        + " user=" + userId + ": " + reason);
4574            } else {
4575                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4576            }
4577
4578            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4579            for (int ip=pmap.size()-1; ip>=0; ip--) {
4580                SparseArray<Long> ba = pmap.valueAt(ip);
4581                for (i=ba.size()-1; i>=0; i--) {
4582                    boolean remove = false;
4583                    final int entUid = ba.keyAt(i);
4584                    if (name != null) {
4585                        if (userId == UserHandle.USER_ALL) {
4586                            if (UserHandle.getAppId(entUid) == appId) {
4587                                remove = true;
4588                            }
4589                        } else {
4590                            if (entUid == UserHandle.getUid(userId, appId)) {
4591                                remove = true;
4592                            }
4593                        }
4594                    } else if (UserHandle.getUserId(entUid) == userId) {
4595                        remove = true;
4596                    }
4597                    if (remove) {
4598                        ba.removeAt(i);
4599                    }
4600                }
4601                if (ba.size() == 0) {
4602                    pmap.removeAt(ip);
4603                }
4604            }
4605        }
4606
4607        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4608                -100, callerWillRestart, true, doit, evenPersistent,
4609                name == null ? ("stop user " + userId) : ("stop " + name));
4610
4611        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4612            if (!doit) {
4613                return true;
4614            }
4615            didSomething = true;
4616        }
4617
4618        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4619            if (!doit) {
4620                return true;
4621            }
4622            didSomething = true;
4623        }
4624
4625        if (name == null) {
4626            // Remove all sticky broadcasts from this user.
4627            mStickyBroadcasts.remove(userId);
4628        }
4629
4630        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4631        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4632                userId, providers)) {
4633            if (!doit) {
4634                return true;
4635            }
4636            didSomething = true;
4637        }
4638        N = providers.size();
4639        for (i=0; i<N; i++) {
4640            removeDyingProviderLocked(null, providers.get(i), true);
4641        }
4642
4643        // Remove transient permissions granted from/to this package/user
4644        removeUriPermissionsForPackageLocked(name, userId, false);
4645
4646        if (name == null || uninstalling) {
4647            // Remove pending intents.  For now we only do this when force
4648            // stopping users, because we have some problems when doing this
4649            // for packages -- app widgets are not currently cleaned up for
4650            // such packages, so they can be left with bad pending intents.
4651            if (mIntentSenderRecords.size() > 0) {
4652                Iterator<WeakReference<PendingIntentRecord>> it
4653                        = mIntentSenderRecords.values().iterator();
4654                while (it.hasNext()) {
4655                    WeakReference<PendingIntentRecord> wpir = it.next();
4656                    if (wpir == null) {
4657                        it.remove();
4658                        continue;
4659                    }
4660                    PendingIntentRecord pir = wpir.get();
4661                    if (pir == null) {
4662                        it.remove();
4663                        continue;
4664                    }
4665                    if (name == null) {
4666                        // Stopping user, remove all objects for the user.
4667                        if (pir.key.userId != userId) {
4668                            // Not the same user, skip it.
4669                            continue;
4670                        }
4671                    } else {
4672                        if (UserHandle.getAppId(pir.uid) != appId) {
4673                            // Different app id, skip it.
4674                            continue;
4675                        }
4676                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4677                            // Different user, skip it.
4678                            continue;
4679                        }
4680                        if (!pir.key.packageName.equals(name)) {
4681                            // Different package, skip it.
4682                            continue;
4683                        }
4684                    }
4685                    if (!doit) {
4686                        return true;
4687                    }
4688                    didSomething = true;
4689                    it.remove();
4690                    pir.canceled = true;
4691                    if (pir.key.activity != null) {
4692                        pir.key.activity.pendingResults.remove(pir.ref);
4693                    }
4694                }
4695            }
4696        }
4697
4698        if (doit) {
4699            if (purgeCache && name != null) {
4700                AttributeCache ac = AttributeCache.instance();
4701                if (ac != null) {
4702                    ac.removePackage(name);
4703                }
4704            }
4705            if (mBooted) {
4706                mStackSupervisor.resumeTopActivitiesLocked();
4707                mStackSupervisor.scheduleIdleLocked();
4708            }
4709        }
4710
4711        return didSomething;
4712    }
4713
4714    private final boolean removeProcessLocked(ProcessRecord app,
4715            boolean callerWillRestart, boolean allowRestart, String reason) {
4716        final String name = app.processName;
4717        final int uid = app.uid;
4718        if (DEBUG_PROCESSES) Slog.d(
4719            TAG, "Force removing proc " + app.toShortString() + " (" + name
4720            + "/" + uid + ")");
4721
4722        mProcessNames.remove(name, uid);
4723        mIsolatedProcesses.remove(app.uid);
4724        if (mHeavyWeightProcess == app) {
4725            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4726                    mHeavyWeightProcess.userId, 0));
4727            mHeavyWeightProcess = null;
4728        }
4729        boolean needRestart = false;
4730        if (app.pid > 0 && app.pid != MY_PID) {
4731            int pid = app.pid;
4732            synchronized (mPidsSelfLocked) {
4733                mPidsSelfLocked.remove(pid);
4734                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4735            }
4736            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISHED,
4737                    app.processName, app.info.uid);
4738            if (app.isolated) {
4739                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4740            }
4741            killUnneededProcessLocked(app, reason);
4742            handleAppDiedLocked(app, true, allowRestart);
4743            removeLruProcessLocked(app);
4744
4745            if (app.persistent && !app.isolated) {
4746                if (!callerWillRestart) {
4747                    addAppLocked(app.info, false);
4748                } else {
4749                    needRestart = true;
4750                }
4751            }
4752        } else {
4753            mRemovedProcesses.add(app);
4754        }
4755
4756        return needRestart;
4757    }
4758
4759    private final void processStartTimedOutLocked(ProcessRecord app) {
4760        final int pid = app.pid;
4761        boolean gone = false;
4762        synchronized (mPidsSelfLocked) {
4763            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4764            if (knownApp != null && knownApp.thread == null) {
4765                mPidsSelfLocked.remove(pid);
4766                gone = true;
4767            }
4768        }
4769
4770        if (gone) {
4771            Slog.w(TAG, "Process " + app + " failed to attach");
4772            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4773                    pid, app.uid, app.processName);
4774            mProcessNames.remove(app.processName, app.uid);
4775            mIsolatedProcesses.remove(app.uid);
4776            if (mHeavyWeightProcess == app) {
4777                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4778                        mHeavyWeightProcess.userId, 0));
4779                mHeavyWeightProcess = null;
4780            }
4781            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISHED,
4782                    app.processName, app.info.uid);
4783            if (app.isolated) {
4784                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4785            }
4786            // Take care of any launching providers waiting for this process.
4787            checkAppInLaunchingProvidersLocked(app, true);
4788            // Take care of any services that are waiting for the process.
4789            mServices.processStartTimedOutLocked(app);
4790            killUnneededProcessLocked(app, "start timeout");
4791            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4792                Slog.w(TAG, "Unattached app died before backup, skipping");
4793                try {
4794                    IBackupManager bm = IBackupManager.Stub.asInterface(
4795                            ServiceManager.getService(Context.BACKUP_SERVICE));
4796                    bm.agentDisconnected(app.info.packageName);
4797                } catch (RemoteException e) {
4798                    // Can't happen; the backup manager is local
4799                }
4800            }
4801            if (isPendingBroadcastProcessLocked(pid)) {
4802                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4803                skipPendingBroadcastLocked(pid);
4804            }
4805        } else {
4806            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4807        }
4808    }
4809
4810    private final boolean attachApplicationLocked(IApplicationThread thread,
4811            int pid) {
4812
4813        // Find the application record that is being attached...  either via
4814        // the pid if we are running in multiple processes, or just pull the
4815        // next app record if we are emulating process with anonymous threads.
4816        ProcessRecord app;
4817        if (pid != MY_PID && pid >= 0) {
4818            synchronized (mPidsSelfLocked) {
4819                app = mPidsSelfLocked.get(pid);
4820            }
4821        } else {
4822            app = null;
4823        }
4824
4825        if (app == null) {
4826            Slog.w(TAG, "No pending application record for pid " + pid
4827                    + " (IApplicationThread " + thread + "); dropping process");
4828            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4829            if (pid > 0 && pid != MY_PID) {
4830                Process.killProcessQuiet(pid);
4831            } else {
4832                try {
4833                    thread.scheduleExit();
4834                } catch (Exception e) {
4835                    // Ignore exceptions.
4836                }
4837            }
4838            return false;
4839        }
4840
4841        // If this application record is still attached to a previous
4842        // process, clean it up now.
4843        if (app.thread != null) {
4844            handleAppDiedLocked(app, true, true);
4845        }
4846
4847        // Tell the process all about itself.
4848
4849        if (localLOGV) Slog.v(
4850                TAG, "Binding process pid " + pid + " to record " + app);
4851
4852        final String processName = app.processName;
4853        try {
4854            AppDeathRecipient adr = new AppDeathRecipient(
4855                    app, pid, thread);
4856            thread.asBinder().linkToDeath(adr, 0);
4857            app.deathRecipient = adr;
4858        } catch (RemoteException e) {
4859            app.resetPackageList(mProcessStats);
4860            startProcessLocked(app, "link fail", processName);
4861            return false;
4862        }
4863
4864        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4865
4866        app.makeActive(thread, mProcessStats);
4867        app.curAdj = app.setAdj = -100;
4868        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4869        app.forcingToForeground = null;
4870        app.foregroundServices = false;
4871        app.hasShownUi = false;
4872        app.debugging = false;
4873        app.cached = false;
4874
4875        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4876
4877        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4878        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4879
4880        if (!normalMode) {
4881            Slog.i(TAG, "Launching preboot mode app: " + app);
4882        }
4883
4884        if (localLOGV) Slog.v(
4885            TAG, "New app record " + app
4886            + " thread=" + thread.asBinder() + " pid=" + pid);
4887        try {
4888            int testMode = IApplicationThread.DEBUG_OFF;
4889            if (mDebugApp != null && mDebugApp.equals(processName)) {
4890                testMode = mWaitForDebugger
4891                    ? IApplicationThread.DEBUG_WAIT
4892                    : IApplicationThread.DEBUG_ON;
4893                app.debugging = true;
4894                if (mDebugTransient) {
4895                    mDebugApp = mOrigDebugApp;
4896                    mWaitForDebugger = mOrigWaitForDebugger;
4897                }
4898            }
4899            String profileFile = app.instrumentationProfileFile;
4900            ParcelFileDescriptor profileFd = null;
4901            boolean profileAutoStop = false;
4902            if (mProfileApp != null && mProfileApp.equals(processName)) {
4903                mProfileProc = app;
4904                profileFile = mProfileFile;
4905                profileFd = mProfileFd;
4906                profileAutoStop = mAutoStopProfiler;
4907            }
4908            boolean enableOpenGlTrace = false;
4909            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4910                enableOpenGlTrace = true;
4911                mOpenGlTraceApp = null;
4912            }
4913
4914            // If the app is being launched for restore or full backup, set it up specially
4915            boolean isRestrictedBackupMode = false;
4916            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4917                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4918                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4919                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4920            }
4921
4922            ensurePackageDexOpt(app.instrumentationInfo != null
4923                    ? app.instrumentationInfo.packageName
4924                    : app.info.packageName);
4925            if (app.instrumentationClass != null) {
4926                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4927            }
4928            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4929                    + processName + " with config " + mConfiguration);
4930            ApplicationInfo appInfo = app.instrumentationInfo != null
4931                    ? app.instrumentationInfo : app.info;
4932            app.compat = compatibilityInfoForPackageLocked(appInfo);
4933            if (profileFd != null) {
4934                profileFd = profileFd.dup();
4935            }
4936            thread.bindApplication(processName, appInfo, providers,
4937                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4938                    app.instrumentationArguments, app.instrumentationWatcher,
4939                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4940                    isRestrictedBackupMode || !normalMode, app.persistent,
4941                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4942                    mCoreSettingsObserver.getCoreSettingsLocked());
4943            updateLruProcessLocked(app, false, null);
4944            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4945        } catch (Exception e) {
4946            // todo: Yikes!  What should we do?  For now we will try to
4947            // start another process, but that could easily get us in
4948            // an infinite loop of restarting processes...
4949            Slog.w(TAG, "Exception thrown during bind!", e);
4950
4951            app.resetPackageList(mProcessStats);
4952            app.unlinkDeathRecipient();
4953            startProcessLocked(app, "bind fail", processName);
4954            return false;
4955        }
4956
4957        // Remove this record from the list of starting applications.
4958        mPersistentStartingProcesses.remove(app);
4959        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4960                "Attach application locked removing on hold: " + app);
4961        mProcessesOnHold.remove(app);
4962
4963        boolean badApp = false;
4964        boolean didSomething = false;
4965
4966        // See if the top visible activity is waiting to run in this process...
4967        if (normalMode) {
4968            try {
4969                if (mStackSupervisor.attachApplicationLocked(app)) {
4970                    didSomething = true;
4971                }
4972            } catch (Exception e) {
4973                badApp = true;
4974            }
4975        }
4976
4977        // Find any services that should be running in this process...
4978        if (!badApp) {
4979            try {
4980                didSomething |= mServices.attachApplicationLocked(app, processName);
4981            } catch (Exception e) {
4982                badApp = true;
4983            }
4984        }
4985
4986        // Check if a next-broadcast receiver is in this process...
4987        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4988            try {
4989                didSomething |= sendPendingBroadcastsLocked(app);
4990            } catch (Exception e) {
4991                // If the app died trying to launch the receiver we declare it 'bad'
4992                badApp = true;
4993            }
4994        }
4995
4996        // Check whether the next backup agent is in this process...
4997        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4998            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4999            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5000            try {
5001                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5002                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5003                        mBackupTarget.backupMode);
5004            } catch (Exception e) {
5005                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5006                e.printStackTrace();
5007            }
5008        }
5009
5010        if (badApp) {
5011            // todo: Also need to kill application to deal with all
5012            // kinds of exceptions.
5013            handleAppDiedLocked(app, false, true);
5014            return false;
5015        }
5016
5017        if (!didSomething) {
5018            updateOomAdjLocked();
5019        }
5020
5021        return true;
5022    }
5023
5024    @Override
5025    public final void attachApplication(IApplicationThread thread) {
5026        synchronized (this) {
5027            int callingPid = Binder.getCallingPid();
5028            final long origId = Binder.clearCallingIdentity();
5029            attachApplicationLocked(thread, callingPid);
5030            Binder.restoreCallingIdentity(origId);
5031        }
5032    }
5033
5034    @Override
5035    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5036        final long origId = Binder.clearCallingIdentity();
5037        synchronized (this) {
5038            ActivityStack stack = ActivityRecord.getStackLocked(token);
5039            if (stack != null) {
5040                ActivityRecord r =
5041                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5042                if (stopProfiling) {
5043                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5044                        try {
5045                            mProfileFd.close();
5046                        } catch (IOException e) {
5047                        }
5048                        clearProfilerLocked();
5049                    }
5050                }
5051            }
5052        }
5053        Binder.restoreCallingIdentity(origId);
5054    }
5055
5056    void enableScreenAfterBoot() {
5057        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5058                SystemClock.uptimeMillis());
5059        mWindowManager.enableScreenAfterBoot();
5060
5061        synchronized (this) {
5062            updateEventDispatchingLocked();
5063        }
5064    }
5065
5066    @Override
5067    public void showBootMessage(final CharSequence msg, final boolean always) {
5068        enforceNotIsolatedCaller("showBootMessage");
5069        mWindowManager.showBootMessage(msg, always);
5070    }
5071
5072    @Override
5073    public void dismissKeyguardOnNextActivity() {
5074        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5075        final long token = Binder.clearCallingIdentity();
5076        try {
5077            synchronized (this) {
5078                if (DEBUG_LOCKSCREEN) logLockScreen("");
5079                if (mLockScreenShown) {
5080                    mLockScreenShown = false;
5081                    comeOutOfSleepIfNeededLocked();
5082                }
5083                mStackSupervisor.setDismissKeyguard(true);
5084            }
5085        } finally {
5086            Binder.restoreCallingIdentity(token);
5087        }
5088    }
5089
5090    final void finishBooting() {
5091        IntentFilter pkgFilter = new IntentFilter();
5092        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5093        pkgFilter.addDataScheme("package");
5094        mContext.registerReceiver(new BroadcastReceiver() {
5095            @Override
5096            public void onReceive(Context context, Intent intent) {
5097                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5098                if (pkgs != null) {
5099                    for (String pkg : pkgs) {
5100                        synchronized (ActivityManagerService.this) {
5101                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5102                                    "finished booting")) {
5103                                setResultCode(Activity.RESULT_OK);
5104                                return;
5105                            }
5106                        }
5107                    }
5108                }
5109            }
5110        }, pkgFilter);
5111
5112        synchronized (this) {
5113            // Ensure that any processes we had put on hold are now started
5114            // up.
5115            final int NP = mProcessesOnHold.size();
5116            if (NP > 0) {
5117                ArrayList<ProcessRecord> procs =
5118                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5119                for (int ip=0; ip<NP; ip++) {
5120                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5121                            + procs.get(ip));
5122                    startProcessLocked(procs.get(ip), "on-hold", null);
5123                }
5124            }
5125
5126            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5127                // Start looking for apps that are abusing wake locks.
5128                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5129                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5130                // Tell anyone interested that we are done booting!
5131                SystemProperties.set("sys.boot_completed", "1");
5132                SystemProperties.set("dev.bootcomplete", "1");
5133                for (int i=0; i<mStartedUsers.size(); i++) {
5134                    UserStartedState uss = mStartedUsers.valueAt(i);
5135                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5136                        uss.mState = UserStartedState.STATE_RUNNING;
5137                        final int userId = mStartedUsers.keyAt(i);
5138                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5139                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5140                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5141                        broadcastIntentLocked(null, null, intent, null,
5142                                new IIntentReceiver.Stub() {
5143                                    @Override
5144                                    public void performReceive(Intent intent, int resultCode,
5145                                            String data, Bundle extras, boolean ordered,
5146                                            boolean sticky, int sendingUser) {
5147                                        synchronized (ActivityManagerService.this) {
5148                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5149                                                    true, false);
5150                                        }
5151                                    }
5152                                },
5153                                0, null, null,
5154                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5155                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5156                                userId);
5157                    }
5158                }
5159            }
5160        }
5161    }
5162
5163    final void ensureBootCompleted() {
5164        boolean booting;
5165        boolean enableScreen;
5166        synchronized (this) {
5167            booting = mBooting;
5168            mBooting = false;
5169            enableScreen = !mBooted;
5170            mBooted = true;
5171        }
5172
5173        if (booting) {
5174            finishBooting();
5175        }
5176
5177        if (enableScreen) {
5178            enableScreenAfterBoot();
5179        }
5180    }
5181
5182    @Override
5183    public final void activityResumed(IBinder token) {
5184        final long origId = Binder.clearCallingIdentity();
5185        synchronized(this) {
5186            ActivityStack stack = ActivityRecord.getStackLocked(token);
5187            if (stack != null) {
5188                ActivityRecord.activityResumedLocked(token);
5189            }
5190        }
5191        Binder.restoreCallingIdentity(origId);
5192    }
5193
5194    @Override
5195    public final void activityPaused(IBinder token) {
5196        final long origId = Binder.clearCallingIdentity();
5197        synchronized(this) {
5198            ActivityStack stack = ActivityRecord.getStackLocked(token);
5199            if (stack != null) {
5200                stack.activityPausedLocked(token, false);
5201            }
5202        }
5203        Binder.restoreCallingIdentity(origId);
5204    }
5205
5206    @Override
5207    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5208            CharSequence description) {
5209        if (localLOGV) Slog.v(
5210            TAG, "Activity stopped: token=" + token);
5211
5212        // Refuse possible leaked file descriptors
5213        if (icicle != null && icicle.hasFileDescriptors()) {
5214            throw new IllegalArgumentException("File descriptors passed in Bundle");
5215        }
5216
5217        ActivityRecord r = null;
5218
5219        final long origId = Binder.clearCallingIdentity();
5220
5221        synchronized (this) {
5222            r = ActivityRecord.isInStackLocked(token);
5223            if (r != null) {
5224                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5225            }
5226        }
5227
5228        if (r != null) {
5229            sendPendingThumbnail(r, null, null, null, false);
5230        }
5231
5232        trimApplications();
5233
5234        Binder.restoreCallingIdentity(origId);
5235    }
5236
5237    @Override
5238    public final void activityDestroyed(IBinder token) {
5239        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5240        synchronized (this) {
5241            ActivityStack stack = ActivityRecord.getStackLocked(token);
5242            if (stack != null) {
5243                stack.activityDestroyedLocked(token);
5244            }
5245        }
5246    }
5247
5248    @Override
5249    public String getCallingPackage(IBinder token) {
5250        synchronized (this) {
5251            ActivityRecord r = getCallingRecordLocked(token);
5252            return r != null ? r.info.packageName : null;
5253        }
5254    }
5255
5256    @Override
5257    public ComponentName getCallingActivity(IBinder token) {
5258        synchronized (this) {
5259            ActivityRecord r = getCallingRecordLocked(token);
5260            return r != null ? r.intent.getComponent() : null;
5261        }
5262    }
5263
5264    private ActivityRecord getCallingRecordLocked(IBinder token) {
5265        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5266        if (r == null) {
5267            return null;
5268        }
5269        return r.resultTo;
5270    }
5271
5272    @Override
5273    public ComponentName getActivityClassForToken(IBinder token) {
5274        synchronized(this) {
5275            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5276            if (r == null) {
5277                return null;
5278            }
5279            return r.intent.getComponent();
5280        }
5281    }
5282
5283    @Override
5284    public String getPackageForToken(IBinder token) {
5285        synchronized(this) {
5286            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5287            if (r == null) {
5288                return null;
5289            }
5290            return r.packageName;
5291        }
5292    }
5293
5294    @Override
5295    public IIntentSender getIntentSender(int type,
5296            String packageName, IBinder token, String resultWho,
5297            int requestCode, Intent[] intents, String[] resolvedTypes,
5298            int flags, Bundle options, int userId) {
5299        enforceNotIsolatedCaller("getIntentSender");
5300        // Refuse possible leaked file descriptors
5301        if (intents != null) {
5302            if (intents.length < 1) {
5303                throw new IllegalArgumentException("Intents array length must be >= 1");
5304            }
5305            for (int i=0; i<intents.length; i++) {
5306                Intent intent = intents[i];
5307                if (intent != null) {
5308                    if (intent.hasFileDescriptors()) {
5309                        throw new IllegalArgumentException("File descriptors passed in Intent");
5310                    }
5311                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5312                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5313                        throw new IllegalArgumentException(
5314                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5315                    }
5316                    intents[i] = new Intent(intent);
5317                }
5318            }
5319            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5320                throw new IllegalArgumentException(
5321                        "Intent array length does not match resolvedTypes length");
5322            }
5323        }
5324        if (options != null) {
5325            if (options.hasFileDescriptors()) {
5326                throw new IllegalArgumentException("File descriptors passed in options");
5327            }
5328        }
5329
5330        synchronized(this) {
5331            int callingUid = Binder.getCallingUid();
5332            int origUserId = userId;
5333            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5334                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5335                    "getIntentSender", null);
5336            if (origUserId == UserHandle.USER_CURRENT) {
5337                // We don't want to evaluate this until the pending intent is
5338                // actually executed.  However, we do want to always do the
5339                // security checking for it above.
5340                userId = UserHandle.USER_CURRENT;
5341            }
5342            try {
5343                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5344                    int uid = AppGlobals.getPackageManager()
5345                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5346                    if (!UserHandle.isSameApp(callingUid, uid)) {
5347                        String msg = "Permission Denial: getIntentSender() from pid="
5348                            + Binder.getCallingPid()
5349                            + ", uid=" + Binder.getCallingUid()
5350                            + ", (need uid=" + uid + ")"
5351                            + " is not allowed to send as package " + packageName;
5352                        Slog.w(TAG, msg);
5353                        throw new SecurityException(msg);
5354                    }
5355                }
5356
5357                return getIntentSenderLocked(type, packageName, callingUid, userId,
5358                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5359
5360            } catch (RemoteException e) {
5361                throw new SecurityException(e);
5362            }
5363        }
5364    }
5365
5366    IIntentSender getIntentSenderLocked(int type, String packageName,
5367            int callingUid, int userId, IBinder token, String resultWho,
5368            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5369            Bundle options) {
5370        if (DEBUG_MU)
5371            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5372        ActivityRecord activity = null;
5373        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5374            activity = ActivityRecord.isInStackLocked(token);
5375            if (activity == null) {
5376                return null;
5377            }
5378            if (activity.finishing) {
5379                return null;
5380            }
5381        }
5382
5383        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5384        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5385        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5386        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5387                |PendingIntent.FLAG_UPDATE_CURRENT);
5388
5389        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5390                type, packageName, activity, resultWho,
5391                requestCode, intents, resolvedTypes, flags, options, userId);
5392        WeakReference<PendingIntentRecord> ref;
5393        ref = mIntentSenderRecords.get(key);
5394        PendingIntentRecord rec = ref != null ? ref.get() : null;
5395        if (rec != null) {
5396            if (!cancelCurrent) {
5397                if (updateCurrent) {
5398                    if (rec.key.requestIntent != null) {
5399                        rec.key.requestIntent.replaceExtras(intents != null ?
5400                                intents[intents.length - 1] : null);
5401                    }
5402                    if (intents != null) {
5403                        intents[intents.length-1] = rec.key.requestIntent;
5404                        rec.key.allIntents = intents;
5405                        rec.key.allResolvedTypes = resolvedTypes;
5406                    } else {
5407                        rec.key.allIntents = null;
5408                        rec.key.allResolvedTypes = null;
5409                    }
5410                }
5411                return rec;
5412            }
5413            rec.canceled = true;
5414            mIntentSenderRecords.remove(key);
5415        }
5416        if (noCreate) {
5417            return rec;
5418        }
5419        rec = new PendingIntentRecord(this, key, callingUid);
5420        mIntentSenderRecords.put(key, rec.ref);
5421        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5422            if (activity.pendingResults == null) {
5423                activity.pendingResults
5424                        = new HashSet<WeakReference<PendingIntentRecord>>();
5425            }
5426            activity.pendingResults.add(rec.ref);
5427        }
5428        return rec;
5429    }
5430
5431    @Override
5432    public void cancelIntentSender(IIntentSender sender) {
5433        if (!(sender instanceof PendingIntentRecord)) {
5434            return;
5435        }
5436        synchronized(this) {
5437            PendingIntentRecord rec = (PendingIntentRecord)sender;
5438            try {
5439                int uid = AppGlobals.getPackageManager()
5440                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5441                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5442                    String msg = "Permission Denial: cancelIntentSender() from pid="
5443                        + Binder.getCallingPid()
5444                        + ", uid=" + Binder.getCallingUid()
5445                        + " is not allowed to cancel packges "
5446                        + rec.key.packageName;
5447                    Slog.w(TAG, msg);
5448                    throw new SecurityException(msg);
5449                }
5450            } catch (RemoteException e) {
5451                throw new SecurityException(e);
5452            }
5453            cancelIntentSenderLocked(rec, true);
5454        }
5455    }
5456
5457    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5458        rec.canceled = true;
5459        mIntentSenderRecords.remove(rec.key);
5460        if (cleanActivity && rec.key.activity != null) {
5461            rec.key.activity.pendingResults.remove(rec.ref);
5462        }
5463    }
5464
5465    @Override
5466    public String getPackageForIntentSender(IIntentSender pendingResult) {
5467        if (!(pendingResult instanceof PendingIntentRecord)) {
5468            return null;
5469        }
5470        try {
5471            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5472            return res.key.packageName;
5473        } catch (ClassCastException e) {
5474        }
5475        return null;
5476    }
5477
5478    @Override
5479    public int getUidForIntentSender(IIntentSender sender) {
5480        if (sender instanceof PendingIntentRecord) {
5481            try {
5482                PendingIntentRecord res = (PendingIntentRecord)sender;
5483                return res.uid;
5484            } catch (ClassCastException e) {
5485            }
5486        }
5487        return -1;
5488    }
5489
5490    @Override
5491    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5492        if (!(pendingResult instanceof PendingIntentRecord)) {
5493            return false;
5494        }
5495        try {
5496            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5497            if (res.key.allIntents == null) {
5498                return false;
5499            }
5500            for (int i=0; i<res.key.allIntents.length; i++) {
5501                Intent intent = res.key.allIntents[i];
5502                if (intent.getPackage() != null && intent.getComponent() != null) {
5503                    return false;
5504                }
5505            }
5506            return true;
5507        } catch (ClassCastException e) {
5508        }
5509        return false;
5510    }
5511
5512    @Override
5513    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5514        if (!(pendingResult instanceof PendingIntentRecord)) {
5515            return false;
5516        }
5517        try {
5518            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5519            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5520                return true;
5521            }
5522            return false;
5523        } catch (ClassCastException e) {
5524        }
5525        return false;
5526    }
5527
5528    @Override
5529    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5530        if (!(pendingResult instanceof PendingIntentRecord)) {
5531            return null;
5532        }
5533        try {
5534            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5535            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5536        } catch (ClassCastException e) {
5537        }
5538        return null;
5539    }
5540
5541    @Override
5542    public void setProcessLimit(int max) {
5543        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5544                "setProcessLimit()");
5545        synchronized (this) {
5546            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5547            mProcessLimitOverride = max;
5548        }
5549        trimApplications();
5550    }
5551
5552    @Override
5553    public int getProcessLimit() {
5554        synchronized (this) {
5555            return mProcessLimitOverride;
5556        }
5557    }
5558
5559    void foregroundTokenDied(ForegroundToken token) {
5560        synchronized (ActivityManagerService.this) {
5561            synchronized (mPidsSelfLocked) {
5562                ForegroundToken cur
5563                    = mForegroundProcesses.get(token.pid);
5564                if (cur != token) {
5565                    return;
5566                }
5567                mForegroundProcesses.remove(token.pid);
5568                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5569                if (pr == null) {
5570                    return;
5571                }
5572                pr.forcingToForeground = null;
5573                pr.foregroundServices = false;
5574            }
5575            updateOomAdjLocked();
5576        }
5577    }
5578
5579    @Override
5580    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5581        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5582                "setProcessForeground()");
5583        synchronized(this) {
5584            boolean changed = false;
5585
5586            synchronized (mPidsSelfLocked) {
5587                ProcessRecord pr = mPidsSelfLocked.get(pid);
5588                if (pr == null && isForeground) {
5589                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5590                    return;
5591                }
5592                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5593                if (oldToken != null) {
5594                    oldToken.token.unlinkToDeath(oldToken, 0);
5595                    mForegroundProcesses.remove(pid);
5596                    if (pr != null) {
5597                        pr.forcingToForeground = null;
5598                    }
5599                    changed = true;
5600                }
5601                if (isForeground && token != null) {
5602                    ForegroundToken newToken = new ForegroundToken() {
5603                        @Override
5604                        public void binderDied() {
5605                            foregroundTokenDied(this);
5606                        }
5607                    };
5608                    newToken.pid = pid;
5609                    newToken.token = token;
5610                    try {
5611                        token.linkToDeath(newToken, 0);
5612                        mForegroundProcesses.put(pid, newToken);
5613                        pr.forcingToForeground = token;
5614                        changed = true;
5615                    } catch (RemoteException e) {
5616                        // If the process died while doing this, we will later
5617                        // do the cleanup with the process death link.
5618                    }
5619                }
5620            }
5621
5622            if (changed) {
5623                updateOomAdjLocked();
5624            }
5625        }
5626    }
5627
5628    // =========================================================
5629    // PERMISSIONS
5630    // =========================================================
5631
5632    static class PermissionController extends IPermissionController.Stub {
5633        ActivityManagerService mActivityManagerService;
5634        PermissionController(ActivityManagerService activityManagerService) {
5635            mActivityManagerService = activityManagerService;
5636        }
5637
5638        @Override
5639        public boolean checkPermission(String permission, int pid, int uid) {
5640            return mActivityManagerService.checkPermission(permission, pid,
5641                    uid) == PackageManager.PERMISSION_GRANTED;
5642        }
5643    }
5644
5645    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5646        @Override
5647        public int checkComponentPermission(String permission, int pid, int uid,
5648                int owningUid, boolean exported) {
5649            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5650                    owningUid, exported);
5651        }
5652
5653        @Override
5654        public Object getAMSLock() {
5655            return ActivityManagerService.this;
5656        }
5657    }
5658
5659    /**
5660     * This can be called with or without the global lock held.
5661     */
5662    int checkComponentPermission(String permission, int pid, int uid,
5663            int owningUid, boolean exported) {
5664        // We might be performing an operation on behalf of an indirect binder
5665        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5666        // client identity accordingly before proceeding.
5667        Identity tlsIdentity = sCallerIdentity.get();
5668        if (tlsIdentity != null) {
5669            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5670                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5671            uid = tlsIdentity.uid;
5672            pid = tlsIdentity.pid;
5673        }
5674
5675        if (pid == MY_PID) {
5676            return PackageManager.PERMISSION_GRANTED;
5677        }
5678
5679        return ActivityManager.checkComponentPermission(permission, uid,
5680                owningUid, exported);
5681    }
5682
5683    /**
5684     * As the only public entry point for permissions checking, this method
5685     * can enforce the semantic that requesting a check on a null global
5686     * permission is automatically denied.  (Internally a null permission
5687     * string is used when calling {@link #checkComponentPermission} in cases
5688     * when only uid-based security is needed.)
5689     *
5690     * This can be called with or without the global lock held.
5691     */
5692    @Override
5693    public int checkPermission(String permission, int pid, int uid) {
5694        if (permission == null) {
5695            return PackageManager.PERMISSION_DENIED;
5696        }
5697        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5698    }
5699
5700    /**
5701     * Binder IPC calls go through the public entry point.
5702     * This can be called with or without the global lock held.
5703     */
5704    int checkCallingPermission(String permission) {
5705        return checkPermission(permission,
5706                Binder.getCallingPid(),
5707                UserHandle.getAppId(Binder.getCallingUid()));
5708    }
5709
5710    /**
5711     * This can be called with or without the global lock held.
5712     */
5713    void enforceCallingPermission(String permission, String func) {
5714        if (checkCallingPermission(permission)
5715                == PackageManager.PERMISSION_GRANTED) {
5716            return;
5717        }
5718
5719        String msg = "Permission Denial: " + func + " from pid="
5720                + Binder.getCallingPid()
5721                + ", uid=" + Binder.getCallingUid()
5722                + " requires " + permission;
5723        Slog.w(TAG, msg);
5724        throw new SecurityException(msg);
5725    }
5726
5727    /**
5728     * Determine if UID is holding permissions required to access {@link Uri} in
5729     * the given {@link ProviderInfo}. Final permission checking is always done
5730     * in {@link ContentProvider}.
5731     */
5732    private final boolean checkHoldingPermissionsLocked(
5733            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5734        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5735                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5736
5737        if (pi.applicationInfo.uid == uid) {
5738            return true;
5739        } else if (!pi.exported) {
5740            return false;
5741        }
5742
5743        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5744        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5745        try {
5746            // check if target holds top-level <provider> permissions
5747            if (!readMet && pi.readPermission != null
5748                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5749                readMet = true;
5750            }
5751            if (!writeMet && pi.writePermission != null
5752                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5753                writeMet = true;
5754            }
5755
5756            // track if unprotected read/write is allowed; any denied
5757            // <path-permission> below removes this ability
5758            boolean allowDefaultRead = pi.readPermission == null;
5759            boolean allowDefaultWrite = pi.writePermission == null;
5760
5761            // check if target holds any <path-permission> that match uri
5762            final PathPermission[] pps = pi.pathPermissions;
5763            if (pps != null) {
5764                final String path = uri.getPath();
5765                int i = pps.length;
5766                while (i > 0 && (!readMet || !writeMet)) {
5767                    i--;
5768                    PathPermission pp = pps[i];
5769                    if (pp.match(path)) {
5770                        if (!readMet) {
5771                            final String pprperm = pp.getReadPermission();
5772                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5773                                    + pprperm + " for " + pp.getPath()
5774                                    + ": match=" + pp.match(path)
5775                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5776                            if (pprperm != null) {
5777                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5778                                    readMet = true;
5779                                } else {
5780                                    allowDefaultRead = false;
5781                                }
5782                            }
5783                        }
5784                        if (!writeMet) {
5785                            final String ppwperm = pp.getWritePermission();
5786                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5787                                    + ppwperm + " for " + pp.getPath()
5788                                    + ": match=" + pp.match(path)
5789                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5790                            if (ppwperm != null) {
5791                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5792                                    writeMet = true;
5793                                } else {
5794                                    allowDefaultWrite = false;
5795                                }
5796                            }
5797                        }
5798                    }
5799                }
5800            }
5801
5802            // grant unprotected <provider> read/write, if not blocked by
5803            // <path-permission> above
5804            if (allowDefaultRead) readMet = true;
5805            if (allowDefaultWrite) writeMet = true;
5806
5807        } catch (RemoteException e) {
5808            return false;
5809        }
5810
5811        return readMet && writeMet;
5812    }
5813
5814    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5815        ProviderInfo pi = null;
5816        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5817        if (cpr != null) {
5818            pi = cpr.info;
5819        } else {
5820            try {
5821                pi = AppGlobals.getPackageManager().resolveContentProvider(
5822                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5823            } catch (RemoteException ex) {
5824            }
5825        }
5826        return pi;
5827    }
5828
5829    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5830        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5831        if (targetUris != null) {
5832            return targetUris.get(uri);
5833        } else {
5834            return null;
5835        }
5836    }
5837
5838    private UriPermission findOrCreateUriPermissionLocked(
5839            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5840        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5841        if (targetUris == null) {
5842            targetUris = Maps.newArrayMap();
5843            mGrantedUriPermissions.put(targetUid, targetUris);
5844        }
5845
5846        UriPermission perm = targetUris.get(uri);
5847        if (perm == null) {
5848            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5849            targetUris.put(uri, perm);
5850        }
5851
5852        return perm;
5853    }
5854
5855    private final boolean checkUriPermissionLocked(
5856            Uri uri, int uid, int modeFlags, int minStrength) {
5857        // Root gets to do everything.
5858        if (uid == 0) {
5859            return true;
5860        }
5861        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5862        if (perms == null) return false;
5863        UriPermission perm = perms.get(uri);
5864        if (perm == null) return false;
5865        return perm.getStrength(modeFlags) >= minStrength;
5866    }
5867
5868    @Override
5869    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5870        enforceNotIsolatedCaller("checkUriPermission");
5871
5872        // Another redirected-binder-call permissions check as in
5873        // {@link checkComponentPermission}.
5874        Identity tlsIdentity = sCallerIdentity.get();
5875        if (tlsIdentity != null) {
5876            uid = tlsIdentity.uid;
5877            pid = tlsIdentity.pid;
5878        }
5879
5880        // Our own process gets to do everything.
5881        if (pid == MY_PID) {
5882            return PackageManager.PERMISSION_GRANTED;
5883        }
5884        synchronized(this) {
5885            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5886                    ? PackageManager.PERMISSION_GRANTED
5887                    : PackageManager.PERMISSION_DENIED;
5888        }
5889    }
5890
5891    /**
5892     * Check if the targetPkg can be granted permission to access uri by
5893     * the callingUid using the given modeFlags.  Throws a security exception
5894     * if callingUid is not allowed to do this.  Returns the uid of the target
5895     * if the URI permission grant should be performed; returns -1 if it is not
5896     * needed (for example targetPkg already has permission to access the URI).
5897     * If you already know the uid of the target, you can supply it in
5898     * lastTargetUid else set that to -1.
5899     */
5900    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5901            Uri uri, int modeFlags, int lastTargetUid) {
5902        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5903        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5904                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5905        if (modeFlags == 0) {
5906            return -1;
5907        }
5908
5909        if (targetPkg != null) {
5910            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5911                    "Checking grant " + targetPkg + " permission to " + uri);
5912        }
5913
5914        final IPackageManager pm = AppGlobals.getPackageManager();
5915
5916        // If this is not a content: uri, we can't do anything with it.
5917        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5918            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5919                    "Can't grant URI permission for non-content URI: " + uri);
5920            return -1;
5921        }
5922
5923        final String authority = uri.getAuthority();
5924        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5925        if (pi == null) {
5926            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5927            return -1;
5928        }
5929
5930        int targetUid = lastTargetUid;
5931        if (targetUid < 0 && targetPkg != null) {
5932            try {
5933                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5934                if (targetUid < 0) {
5935                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5936                            "Can't grant URI permission no uid for: " + targetPkg);
5937                    return -1;
5938                }
5939            } catch (RemoteException ex) {
5940                return -1;
5941            }
5942        }
5943
5944        if (targetUid >= 0) {
5945            // First...  does the target actually need this permission?
5946            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5947                // No need to grant the target this permission.
5948                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5949                        "Target " + targetPkg + " already has full permission to " + uri);
5950                return -1;
5951            }
5952        } else {
5953            // First...  there is no target package, so can anyone access it?
5954            boolean allowed = pi.exported;
5955            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5956                if (pi.readPermission != null) {
5957                    allowed = false;
5958                }
5959            }
5960            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5961                if (pi.writePermission != null) {
5962                    allowed = false;
5963                }
5964            }
5965            if (allowed) {
5966                return -1;
5967            }
5968        }
5969
5970        // Second...  is the provider allowing granting of URI permissions?
5971        if (!pi.grantUriPermissions) {
5972            throw new SecurityException("Provider " + pi.packageName
5973                    + "/" + pi.name
5974                    + " does not allow granting of Uri permissions (uri "
5975                    + uri + ")");
5976        }
5977        if (pi.uriPermissionPatterns != null) {
5978            final int N = pi.uriPermissionPatterns.length;
5979            boolean allowed = false;
5980            for (int i=0; i<N; i++) {
5981                if (pi.uriPermissionPatterns[i] != null
5982                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5983                    allowed = true;
5984                    break;
5985                }
5986            }
5987            if (!allowed) {
5988                throw new SecurityException("Provider " + pi.packageName
5989                        + "/" + pi.name
5990                        + " does not allow granting of permission to path of Uri "
5991                        + uri);
5992            }
5993        }
5994
5995        // Third...  does the caller itself have permission to access
5996        // this uri?
5997        if (callingUid != Process.myUid()) {
5998            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5999                // Require they hold a strong enough Uri permission
6000                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6001                        : UriPermission.STRENGTH_OWNED;
6002                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6003                    throw new SecurityException("Uid " + callingUid
6004                            + " does not have permission to uri " + uri);
6005                }
6006            }
6007        }
6008
6009        return targetUid;
6010    }
6011
6012    @Override
6013    public int checkGrantUriPermission(int callingUid, String targetPkg,
6014            Uri uri, int modeFlags) {
6015        enforceNotIsolatedCaller("checkGrantUriPermission");
6016        synchronized(this) {
6017            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6018        }
6019    }
6020
6021    void grantUriPermissionUncheckedLocked(
6022            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6023        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6024        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6025                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6026        if (modeFlags == 0) {
6027            return;
6028        }
6029
6030        // So here we are: the caller has the assumed permission
6031        // to the uri, and the target doesn't.  Let's now give this to
6032        // the target.
6033
6034        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6035                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6036
6037        final String authority = uri.getAuthority();
6038        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6039        if (pi == null) {
6040            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6041            return;
6042        }
6043
6044        final UriPermission perm = findOrCreateUriPermissionLocked(
6045                pi.packageName, targetPkg, targetUid, uri);
6046        perm.grantModes(modeFlags, persistable, owner);
6047    }
6048
6049    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6050            int modeFlags, UriPermissionOwner owner) {
6051        if (targetPkg == null) {
6052            throw new NullPointerException("targetPkg");
6053        }
6054
6055        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6056        if (targetUid < 0) {
6057            return;
6058        }
6059
6060        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6061    }
6062
6063    static class NeededUriGrants extends ArrayList<Uri> {
6064        final String targetPkg;
6065        final int targetUid;
6066        final int flags;
6067
6068        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6069            this.targetPkg = targetPkg;
6070            this.targetUid = targetUid;
6071            this.flags = flags;
6072        }
6073    }
6074
6075    /**
6076     * Like checkGrantUriPermissionLocked, but takes an Intent.
6077     */
6078    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6079            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6080        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6081                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6082                + " clip=" + (intent != null ? intent.getClipData() : null)
6083                + " from " + intent + "; flags=0x"
6084                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6085
6086        if (targetPkg == null) {
6087            throw new NullPointerException("targetPkg");
6088        }
6089
6090        if (intent == null) {
6091            return null;
6092        }
6093        Uri data = intent.getData();
6094        ClipData clip = intent.getClipData();
6095        if (data == null && clip == null) {
6096            return null;
6097        }
6098
6099        if (data != null) {
6100            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6101                mode, needed != null ? needed.targetUid : -1);
6102            if (targetUid > 0) {
6103                if (needed == null) {
6104                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6105                }
6106                needed.add(data);
6107            }
6108        }
6109        if (clip != null) {
6110            for (int i=0; i<clip.getItemCount(); i++) {
6111                Uri uri = clip.getItemAt(i).getUri();
6112                if (uri != null) {
6113                    int targetUid = -1;
6114                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6115                            mode, needed != null ? needed.targetUid : -1);
6116                    if (targetUid > 0) {
6117                        if (needed == null) {
6118                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6119                        }
6120                        needed.add(uri);
6121                    }
6122                } else {
6123                    Intent clipIntent = clip.getItemAt(i).getIntent();
6124                    if (clipIntent != null) {
6125                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6126                                callingUid, targetPkg, clipIntent, mode, needed);
6127                        if (newNeeded != null) {
6128                            needed = newNeeded;
6129                        }
6130                    }
6131                }
6132            }
6133        }
6134
6135        return needed;
6136    }
6137
6138    /**
6139     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6140     */
6141    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6142            UriPermissionOwner owner) {
6143        if (needed != null) {
6144            for (int i=0; i<needed.size(); i++) {
6145                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6146                        needed.get(i), needed.flags, owner);
6147            }
6148        }
6149    }
6150
6151    void grantUriPermissionFromIntentLocked(int callingUid,
6152            String targetPkg, Intent intent, UriPermissionOwner owner) {
6153        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6154                intent, intent != null ? intent.getFlags() : 0, null);
6155        if (needed == null) {
6156            return;
6157        }
6158
6159        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6160    }
6161
6162    @Override
6163    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6164            Uri uri, int modeFlags) {
6165        enforceNotIsolatedCaller("grantUriPermission");
6166        synchronized(this) {
6167            final ProcessRecord r = getRecordForAppLocked(caller);
6168            if (r == null) {
6169                throw new SecurityException("Unable to find app for caller "
6170                        + caller
6171                        + " when granting permission to uri " + uri);
6172            }
6173            if (targetPkg == null) {
6174                throw new IllegalArgumentException("null target");
6175            }
6176            if (uri == null) {
6177                throw new IllegalArgumentException("null uri");
6178            }
6179
6180            // Persistable only supported through Intents
6181            Preconditions.checkFlagsArgument(modeFlags,
6182                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6183
6184            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6185                    null);
6186        }
6187    }
6188
6189    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6190        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6191                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6192            ArrayMap<Uri, UriPermission> perms
6193                    = mGrantedUriPermissions.get(perm.targetUid);
6194            if (perms != null) {
6195                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6196                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6197                perms.remove(perm.uri);
6198                if (perms.size() == 0) {
6199                    mGrantedUriPermissions.remove(perm.targetUid);
6200                }
6201            }
6202        }
6203    }
6204
6205    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6206        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6207
6208        final IPackageManager pm = AppGlobals.getPackageManager();
6209        final String authority = uri.getAuthority();
6210        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6211        if (pi == null) {
6212            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6213            return;
6214        }
6215
6216        // Does the caller have this permission on the URI?
6217        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6218            // Right now, if you are not the original owner of the permission,
6219            // you are not allowed to revoke it.
6220            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6221                throw new SecurityException("Uid " + callingUid
6222                        + " does not have permission to uri " + uri);
6223            //}
6224        }
6225
6226        boolean persistChanged = false;
6227
6228        // Go through all of the permissions and remove any that match.
6229        final List<String> SEGMENTS = uri.getPathSegments();
6230        if (SEGMENTS != null) {
6231            final int NS = SEGMENTS.size();
6232            int N = mGrantedUriPermissions.size();
6233            for (int i=0; i<N; i++) {
6234                ArrayMap<Uri, UriPermission> perms
6235                        = mGrantedUriPermissions.valueAt(i);
6236                Iterator<UriPermission> it = perms.values().iterator();
6237            toploop:
6238                while (it.hasNext()) {
6239                    UriPermission perm = it.next();
6240                    Uri targetUri = perm.uri;
6241                    if (!authority.equals(targetUri.getAuthority())) {
6242                        continue;
6243                    }
6244                    List<String> targetSegments = targetUri.getPathSegments();
6245                    if (targetSegments == null) {
6246                        continue;
6247                    }
6248                    if (targetSegments.size() < NS) {
6249                        continue;
6250                    }
6251                    for (int j=0; j<NS; j++) {
6252                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6253                            continue toploop;
6254                        }
6255                    }
6256                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6257                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6258                    persistChanged |= perm.clearModes(modeFlags, true);
6259                    if (perm.modeFlags == 0) {
6260                        it.remove();
6261                    }
6262                }
6263                if (perms.size() == 0) {
6264                    mGrantedUriPermissions.remove(
6265                            mGrantedUriPermissions.keyAt(i));
6266                    N--;
6267                    i--;
6268                }
6269            }
6270        }
6271
6272        if (persistChanged) {
6273            schedulePersistUriGrants();
6274        }
6275    }
6276
6277    @Override
6278    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6279            int modeFlags) {
6280        enforceNotIsolatedCaller("revokeUriPermission");
6281        synchronized(this) {
6282            final ProcessRecord r = getRecordForAppLocked(caller);
6283            if (r == null) {
6284                throw new SecurityException("Unable to find app for caller "
6285                        + caller
6286                        + " when revoking permission to uri " + uri);
6287            }
6288            if (uri == null) {
6289                Slog.w(TAG, "revokeUriPermission: null uri");
6290                return;
6291            }
6292
6293            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6294                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6295            if (modeFlags == 0) {
6296                return;
6297            }
6298
6299            final IPackageManager pm = AppGlobals.getPackageManager();
6300            final String authority = uri.getAuthority();
6301            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6302            if (pi == null) {
6303                Slog.w(TAG, "No content provider found for permission revoke: "
6304                        + uri.toSafeString());
6305                return;
6306            }
6307
6308            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6309        }
6310    }
6311
6312    /**
6313     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6314     * given package.
6315     *
6316     * @param packageName Package name to match, or {@code null} to apply to all
6317     *            packages.
6318     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6319     *            to all users.
6320     * @param persistable If persistable grants should be removed.
6321     */
6322    private void removeUriPermissionsForPackageLocked(
6323            String packageName, int userHandle, boolean persistable) {
6324        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6325            throw new IllegalArgumentException("Must narrow by either package or user");
6326        }
6327
6328        boolean persistChanged = false;
6329
6330        final int size = mGrantedUriPermissions.size();
6331        for (int i = 0; i < size; i++) {
6332            // Only inspect grants matching user
6333            if (userHandle == UserHandle.USER_ALL
6334                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6335                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6336                        .values().iterator();
6337                while (it.hasNext()) {
6338                    final UriPermission perm = it.next();
6339
6340                    // Only inspect grants matching package
6341                    if (packageName == null || perm.sourcePkg.equals(packageName)
6342                            || perm.targetPkg.equals(packageName)) {
6343                        persistChanged |= perm.clearModes(~0, persistable);
6344
6345                        // Only remove when no modes remain; any persisted grants
6346                        // will keep this alive.
6347                        if (perm.modeFlags == 0) {
6348                            it.remove();
6349                        }
6350                    }
6351                }
6352            }
6353        }
6354
6355        if (persistChanged) {
6356            schedulePersistUriGrants();
6357        }
6358    }
6359
6360    @Override
6361    public IBinder newUriPermissionOwner(String name) {
6362        enforceNotIsolatedCaller("newUriPermissionOwner");
6363        synchronized(this) {
6364            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6365            return owner.getExternalTokenLocked();
6366        }
6367    }
6368
6369    @Override
6370    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6371            Uri uri, int modeFlags) {
6372        synchronized(this) {
6373            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6374            if (owner == null) {
6375                throw new IllegalArgumentException("Unknown owner: " + token);
6376            }
6377            if (fromUid != Binder.getCallingUid()) {
6378                if (Binder.getCallingUid() != Process.myUid()) {
6379                    // Only system code can grant URI permissions on behalf
6380                    // of other users.
6381                    throw new SecurityException("nice try");
6382                }
6383            }
6384            if (targetPkg == null) {
6385                throw new IllegalArgumentException("null target");
6386            }
6387            if (uri == null) {
6388                throw new IllegalArgumentException("null uri");
6389            }
6390
6391            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6392        }
6393    }
6394
6395    @Override
6396    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6397        synchronized(this) {
6398            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6399            if (owner == null) {
6400                throw new IllegalArgumentException("Unknown owner: " + token);
6401            }
6402
6403            if (uri == null) {
6404                owner.removeUriPermissionsLocked(mode);
6405            } else {
6406                owner.removeUriPermissionLocked(uri, mode);
6407            }
6408        }
6409    }
6410
6411    private void schedulePersistUriGrants() {
6412        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6413            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6414                    10 * DateUtils.SECOND_IN_MILLIS);
6415        }
6416    }
6417
6418    private void writeGrantedUriPermissions() {
6419        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6420
6421        // Snapshot permissions so we can persist without lock
6422        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6423        synchronized (this) {
6424            final int size = mGrantedUriPermissions.size();
6425            for (int i = 0 ; i < size; i++) {
6426                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6427                    if (perm.persistedModeFlags != 0) {
6428                        persist.add(perm.snapshot());
6429                    }
6430                }
6431            }
6432        }
6433
6434        FileOutputStream fos = null;
6435        try {
6436            fos = mGrantFile.startWrite();
6437
6438            XmlSerializer out = new FastXmlSerializer();
6439            out.setOutput(fos, "utf-8");
6440            out.startDocument(null, true);
6441            out.startTag(null, TAG_URI_GRANTS);
6442            for (UriPermission.Snapshot perm : persist) {
6443                out.startTag(null, TAG_URI_GRANT);
6444                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6445                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6446                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6447                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6448                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6449                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6450                out.endTag(null, TAG_URI_GRANT);
6451            }
6452            out.endTag(null, TAG_URI_GRANTS);
6453            out.endDocument();
6454
6455            mGrantFile.finishWrite(fos);
6456        } catch (IOException e) {
6457            if (fos != null) {
6458                mGrantFile.failWrite(fos);
6459            }
6460        }
6461    }
6462
6463    private void readGrantedUriPermissionsLocked() {
6464        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6465
6466        final long now = System.currentTimeMillis();
6467
6468        FileInputStream fis = null;
6469        try {
6470            fis = mGrantFile.openRead();
6471            final XmlPullParser in = Xml.newPullParser();
6472            in.setInput(fis, null);
6473
6474            int type;
6475            while ((type = in.next()) != END_DOCUMENT) {
6476                final String tag = in.getName();
6477                if (type == START_TAG) {
6478                    if (TAG_URI_GRANT.equals(tag)) {
6479                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6480                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6481                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6482                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6483                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6484                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6485
6486                        // Sanity check that provider still belongs to source package
6487                        final ProviderInfo pi = getProviderInfoLocked(
6488                                uri.getAuthority(), userHandle);
6489                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6490                            int targetUid = -1;
6491                            try {
6492                                targetUid = AppGlobals.getPackageManager()
6493                                        .getPackageUid(targetPkg, userHandle);
6494                            } catch (RemoteException e) {
6495                            }
6496                            if (targetUid != -1) {
6497                                final UriPermission perm = findOrCreateUriPermissionLocked(
6498                                        sourcePkg, targetPkg, targetUid, uri);
6499                                perm.initPersistedModes(modeFlags, createdTime);
6500                            }
6501                        } else {
6502                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6503                                    + " but instead found " + pi);
6504                        }
6505                    }
6506                }
6507            }
6508        } catch (FileNotFoundException e) {
6509            // Missing grants is okay
6510        } catch (IOException e) {
6511            Log.wtf(TAG, "Failed reading Uri grants", e);
6512        } catch (XmlPullParserException e) {
6513            Log.wtf(TAG, "Failed reading Uri grants", e);
6514        } finally {
6515            IoUtils.closeQuietly(fis);
6516        }
6517    }
6518
6519    @Override
6520    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6521        enforceNotIsolatedCaller("takePersistableUriPermission");
6522
6523        Preconditions.checkFlagsArgument(modeFlags,
6524                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6525
6526        synchronized (this) {
6527            final int callingUid = Binder.getCallingUid();
6528            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6529            if (perm == null) {
6530                throw new SecurityException("No permission grant found for UID " + callingUid
6531                        + " and Uri " + uri.toSafeString());
6532            }
6533
6534            boolean persistChanged = perm.takePersistableModes(modeFlags);
6535            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6536
6537            if (persistChanged) {
6538                schedulePersistUriGrants();
6539            }
6540        }
6541    }
6542
6543    @Override
6544    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6545        enforceNotIsolatedCaller("releasePersistableUriPermission");
6546
6547        Preconditions.checkFlagsArgument(modeFlags,
6548                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6549
6550        synchronized (this) {
6551            final int callingUid = Binder.getCallingUid();
6552
6553            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6554            if (perm == null) {
6555                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6556                        + uri.toSafeString());
6557                return;
6558            }
6559
6560            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6561            removeUriPermissionIfNeededLocked(perm);
6562            if (persistChanged) {
6563                schedulePersistUriGrants();
6564            }
6565        }
6566    }
6567
6568    /**
6569     * Prune any older {@link UriPermission} for the given UID until outstanding
6570     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6571     *
6572     * @return if any mutations occured that require persisting.
6573     */
6574    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6575        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6576        if (perms == null) return false;
6577        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6578
6579        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6580        for (UriPermission perm : perms.values()) {
6581            if (perm.persistedModeFlags != 0) {
6582                persisted.add(perm);
6583            }
6584        }
6585
6586        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6587        if (trimCount <= 0) return false;
6588
6589        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6590        for (int i = 0; i < trimCount; i++) {
6591            final UriPermission perm = persisted.get(i);
6592
6593            if (DEBUG_URI_PERMISSION) {
6594                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6595            }
6596
6597            perm.releasePersistableModes(~0);
6598            removeUriPermissionIfNeededLocked(perm);
6599        }
6600
6601        return true;
6602    }
6603
6604    @Override
6605    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6606            String packageName, boolean incoming) {
6607        enforceNotIsolatedCaller("getPersistedUriPermissions");
6608        Preconditions.checkNotNull(packageName, "packageName");
6609
6610        final int callingUid = Binder.getCallingUid();
6611        final IPackageManager pm = AppGlobals.getPackageManager();
6612        try {
6613            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6614            if (packageUid != callingUid) {
6615                throw new SecurityException(
6616                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6617            }
6618        } catch (RemoteException e) {
6619            throw new SecurityException("Failed to verify package name ownership");
6620        }
6621
6622        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6623        synchronized (this) {
6624            if (incoming) {
6625                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6626                if (perms == null) {
6627                    Slog.w(TAG, "No permission grants found for " + packageName);
6628                } else {
6629                    final int size = perms.size();
6630                    for (int i = 0; i < size; i++) {
6631                        final UriPermission perm = perms.valueAt(i);
6632                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6633                            result.add(perm.buildPersistedPublicApiObject());
6634                        }
6635                    }
6636                }
6637            } else {
6638                final int size = mGrantedUriPermissions.size();
6639                for (int i = 0; i < size; i++) {
6640                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6641                    final int permsSize = perms.size();
6642                    for (int j = 0; j < permsSize; j++) {
6643                        final UriPermission perm = perms.valueAt(j);
6644                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6645                            result.add(perm.buildPersistedPublicApiObject());
6646                        }
6647                    }
6648                }
6649            }
6650        }
6651        return new ParceledListSlice<android.content.UriPermission>(result);
6652    }
6653
6654    @Override
6655    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6656        synchronized (this) {
6657            ProcessRecord app =
6658                who != null ? getRecordForAppLocked(who) : null;
6659            if (app == null) return;
6660
6661            Message msg = Message.obtain();
6662            msg.what = WAIT_FOR_DEBUGGER_MSG;
6663            msg.obj = app;
6664            msg.arg1 = waiting ? 1 : 0;
6665            mHandler.sendMessage(msg);
6666        }
6667    }
6668
6669    @Override
6670    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6671        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6672        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6673        outInfo.availMem = Process.getFreeMemory();
6674        outInfo.totalMem = Process.getTotalMemory();
6675        outInfo.threshold = homeAppMem;
6676        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6677        outInfo.hiddenAppThreshold = cachedAppMem;
6678        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6679                ProcessList.SERVICE_ADJ);
6680        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6681                ProcessList.VISIBLE_APP_ADJ);
6682        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6683                ProcessList.FOREGROUND_APP_ADJ);
6684    }
6685
6686    // =========================================================
6687    // TASK MANAGEMENT
6688    // =========================================================
6689
6690    @Override
6691    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6692                         IThumbnailReceiver receiver) {
6693        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6694
6695        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6696        ActivityRecord topRecord = null;
6697
6698        synchronized(this) {
6699            if (localLOGV) Slog.v(
6700                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6701                + ", receiver=" + receiver);
6702
6703            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6704                    != PackageManager.PERMISSION_GRANTED) {
6705                if (receiver != null) {
6706                    // If the caller wants to wait for pending thumbnails,
6707                    // it ain't gonna get them.
6708                    try {
6709                        receiver.finished();
6710                    } catch (RemoteException ex) {
6711                    }
6712                }
6713                String msg = "Permission Denial: getTasks() from pid="
6714                        + Binder.getCallingPid()
6715                        + ", uid=" + Binder.getCallingUid()
6716                        + " requires " + android.Manifest.permission.GET_TASKS;
6717                Slog.w(TAG, msg);
6718                throw new SecurityException(msg);
6719            }
6720
6721            // TODO: Improve with MRU list from all ActivityStacks.
6722            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6723
6724            if (!pending.pendingRecords.isEmpty()) {
6725                mPendingThumbnails.add(pending);
6726            }
6727        }
6728
6729        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6730
6731        if (topRecord != null) {
6732            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6733            try {
6734                IApplicationThread topThumbnail = topRecord.app.thread;
6735                topThumbnail.requestThumbnail(topRecord.appToken);
6736            } catch (Exception e) {
6737                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6738                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6739            }
6740        }
6741
6742        if (pending == null && receiver != null) {
6743            // In this case all thumbnails were available and the client
6744            // is being asked to be told when the remaining ones come in...
6745            // which is unusually, since the top-most currently running
6746            // activity should never have a canned thumbnail!  Oh well.
6747            try {
6748                receiver.finished();
6749            } catch (RemoteException ex) {
6750            }
6751        }
6752
6753        return list;
6754    }
6755
6756    TaskRecord getMostRecentTask() {
6757        return mRecentTasks.get(0);
6758    }
6759
6760    @Override
6761    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6762            int flags, int userId) {
6763        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6764                false, true, "getRecentTasks", null);
6765
6766        synchronized (this) {
6767            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6768                    "getRecentTasks()");
6769            final boolean detailed = checkCallingPermission(
6770                    android.Manifest.permission.GET_DETAILED_TASKS)
6771                    == PackageManager.PERMISSION_GRANTED;
6772
6773            IPackageManager pm = AppGlobals.getPackageManager();
6774
6775            final int N = mRecentTasks.size();
6776            ArrayList<ActivityManager.RecentTaskInfo> res
6777                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6778                            maxNum < N ? maxNum : N);
6779            for (int i=0; i<N && maxNum > 0; i++) {
6780                TaskRecord tr = mRecentTasks.get(i);
6781                // Only add calling user's recent tasks
6782                if (tr.userId != userId) continue;
6783                // Return the entry if desired by the caller.  We always return
6784                // the first entry, because callers always expect this to be the
6785                // foreground app.  We may filter others if the caller has
6786                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6787                // we should exclude the entry.
6788
6789                if (i == 0
6790                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6791                        || (tr.intent == null)
6792                        || ((tr.intent.getFlags()
6793                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6794                    ActivityManager.RecentTaskInfo rti
6795                            = new ActivityManager.RecentTaskInfo();
6796                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6797                    rti.persistentId = tr.taskId;
6798                    rti.baseIntent = new Intent(
6799                            tr.intent != null ? tr.intent : tr.affinityIntent);
6800                    if (!detailed) {
6801                        rti.baseIntent.replaceExtras((Bundle)null);
6802                    }
6803                    rti.origActivity = tr.origActivity;
6804                    rti.description = tr.lastDescription;
6805                    rti.stackId = tr.stack.mStackId;
6806
6807                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6808                        // Check whether this activity is currently available.
6809                        try {
6810                            if (rti.origActivity != null) {
6811                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6812                                        == null) {
6813                                    continue;
6814                                }
6815                            } else if (rti.baseIntent != null) {
6816                                if (pm.queryIntentActivities(rti.baseIntent,
6817                                        null, 0, userId) == null) {
6818                                    continue;
6819                                }
6820                            }
6821                        } catch (RemoteException e) {
6822                            // Will never happen.
6823                        }
6824                    }
6825
6826                    res.add(rti);
6827                    maxNum--;
6828                }
6829            }
6830            return res;
6831        }
6832    }
6833
6834    private TaskRecord recentTaskForIdLocked(int id) {
6835        final int N = mRecentTasks.size();
6836            for (int i=0; i<N; i++) {
6837                TaskRecord tr = mRecentTasks.get(i);
6838                if (tr.taskId == id) {
6839                    return tr;
6840                }
6841            }
6842            return null;
6843    }
6844
6845    @Override
6846    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6847        synchronized (this) {
6848            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6849                    "getTaskThumbnails()");
6850            TaskRecord tr = recentTaskForIdLocked(id);
6851            if (tr != null) {
6852                return tr.getTaskThumbnailsLocked();
6853            }
6854        }
6855        return null;
6856    }
6857
6858    @Override
6859    public Bitmap getTaskTopThumbnail(int id) {
6860        synchronized (this) {
6861            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6862                    "getTaskTopThumbnail()");
6863            TaskRecord tr = recentTaskForIdLocked(id);
6864            if (tr != null) {
6865                return tr.getTaskTopThumbnailLocked();
6866            }
6867        }
6868        return null;
6869    }
6870
6871    @Override
6872    public boolean removeSubTask(int taskId, int subTaskIndex) {
6873        synchronized (this) {
6874            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6875                    "removeSubTask()");
6876            long ident = Binder.clearCallingIdentity();
6877            try {
6878                TaskRecord tr = recentTaskForIdLocked(taskId);
6879                if (tr != null) {
6880                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6881                }
6882                return false;
6883            } finally {
6884                Binder.restoreCallingIdentity(ident);
6885            }
6886        }
6887    }
6888
6889    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6890        if (!pr.killedByAm) {
6891            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6892            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6893                    pr.processName, pr.setAdj, reason);
6894            pr.killedByAm = true;
6895            Process.killProcessQuiet(pr.pid);
6896        }
6897    }
6898
6899    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6900        tr.disposeThumbnail();
6901        mRecentTasks.remove(tr);
6902        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6903        Intent baseIntent = new Intent(
6904                tr.intent != null ? tr.intent : tr.affinityIntent);
6905        ComponentName component = baseIntent.getComponent();
6906        if (component == null) {
6907            Slog.w(TAG, "Now component for base intent of task: " + tr);
6908            return;
6909        }
6910
6911        // Find any running services associated with this app.
6912        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6913
6914        if (killProcesses) {
6915            // Find any running processes associated with this app.
6916            final String pkg = component.getPackageName();
6917            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6918            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6919            for (int i=0; i<pmap.size(); i++) {
6920                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6921                for (int j=0; j<uids.size(); j++) {
6922                    ProcessRecord proc = uids.valueAt(j);
6923                    if (proc.userId != tr.userId) {
6924                        continue;
6925                    }
6926                    if (!proc.pkgList.containsKey(pkg)) {
6927                        continue;
6928                    }
6929                    procs.add(proc);
6930                }
6931            }
6932
6933            // Kill the running processes.
6934            for (int i=0; i<procs.size(); i++) {
6935                ProcessRecord pr = procs.get(i);
6936                if (pr == mHomeProcess) {
6937                    // Don't kill the home process along with tasks from the same package.
6938                    continue;
6939                }
6940                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6941                    killUnneededProcessLocked(pr, "remove task");
6942                } else {
6943                    pr.waitingToKill = "remove task";
6944                }
6945            }
6946        }
6947    }
6948
6949    @Override
6950    public boolean removeTask(int taskId, int flags) {
6951        synchronized (this) {
6952            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6953                    "removeTask()");
6954            long ident = Binder.clearCallingIdentity();
6955            try {
6956                TaskRecord tr = recentTaskForIdLocked(taskId);
6957                if (tr != null) {
6958                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6959                    if (r != null) {
6960                        cleanUpRemovedTaskLocked(tr, flags);
6961                        return true;
6962                    }
6963                    if (tr.mActivities.size() == 0) {
6964                        // Caller is just removing a recent task that is
6965                        // not actively running.  That is easy!
6966                        cleanUpRemovedTaskLocked(tr, flags);
6967                        return true;
6968                    }
6969                    Slog.w(TAG, "removeTask: task " + taskId
6970                            + " does not have activities to remove, "
6971                            + " but numActivities=" + tr.numActivities
6972                            + ": " + tr);
6973                }
6974            } finally {
6975                Binder.restoreCallingIdentity(ident);
6976            }
6977        }
6978        return false;
6979    }
6980
6981    /**
6982     * TODO: Add mController hook
6983     */
6984    @Override
6985    public void moveTaskToFront(int task, int flags, Bundle options) {
6986        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6987                "moveTaskToFront()");
6988
6989        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
6990        synchronized(this) {
6991            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6992                    Binder.getCallingUid(), "Task to front")) {
6993                ActivityOptions.abort(options);
6994                return;
6995            }
6996            final long origId = Binder.clearCallingIdentity();
6997            try {
6998                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
6999            } finally {
7000                Binder.restoreCallingIdentity(origId);
7001            }
7002            ActivityOptions.abort(options);
7003        }
7004    }
7005
7006    @Override
7007    public void moveTaskToBack(int taskId) {
7008        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7009                "moveTaskToBack()");
7010
7011        synchronized(this) {
7012            TaskRecord tr = recentTaskForIdLocked(taskId);
7013            if (tr != null) {
7014                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7015                ActivityStack stack = tr.stack;
7016                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7017                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7018                            Binder.getCallingUid(), "Task to back")) {
7019                        return;
7020                    }
7021                }
7022                final long origId = Binder.clearCallingIdentity();
7023                try {
7024                    stack.moveTaskToBackLocked(taskId, null);
7025                } finally {
7026                    Binder.restoreCallingIdentity(origId);
7027                }
7028            }
7029        }
7030    }
7031
7032    /**
7033     * Moves an activity, and all of the other activities within the same task, to the bottom
7034     * of the history stack.  The activity's order within the task is unchanged.
7035     *
7036     * @param token A reference to the activity we wish to move
7037     * @param nonRoot If false then this only works if the activity is the root
7038     *                of a task; if true it will work for any activity in a task.
7039     * @return Returns true if the move completed, false if not.
7040     */
7041    @Override
7042    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7043        enforceNotIsolatedCaller("moveActivityTaskToBack");
7044        synchronized(this) {
7045            final long origId = Binder.clearCallingIdentity();
7046            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7047            if (taskId >= 0) {
7048                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7049            }
7050            Binder.restoreCallingIdentity(origId);
7051        }
7052        return false;
7053    }
7054
7055    @Override
7056    public void moveTaskBackwards(int task) {
7057        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7058                "moveTaskBackwards()");
7059
7060        synchronized(this) {
7061            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7062                    Binder.getCallingUid(), "Task backwards")) {
7063                return;
7064            }
7065            final long origId = Binder.clearCallingIdentity();
7066            moveTaskBackwardsLocked(task);
7067            Binder.restoreCallingIdentity(origId);
7068        }
7069    }
7070
7071    private final void moveTaskBackwardsLocked(int task) {
7072        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7073    }
7074
7075    @Override
7076    public IBinder getHomeActivityToken() throws RemoteException {
7077        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7078                "getHomeActivityToken()");
7079        synchronized (this) {
7080            return mStackSupervisor.getHomeActivityToken();
7081        }
7082    }
7083
7084    @Override
7085    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7086            IActivityContainerCallback callback) throws RemoteException {
7087        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7088                "createActivityContainer()");
7089        synchronized (this) {
7090            if (parentActivityToken == null) {
7091                throw new IllegalArgumentException("parent token must not be null");
7092            }
7093            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7094            if (r == null) {
7095                return null;
7096            }
7097            return mStackSupervisor.createActivityContainer(r, callback);
7098        }
7099    }
7100
7101    @Override
7102    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7103            throws RemoteException {
7104        synchronized (this) {
7105            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7106            if (stack != null) {
7107                return stack.mActivityContainer;
7108            }
7109            return null;
7110        }
7111    }
7112
7113    @Override
7114    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7115        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7116                "moveTaskToStack()");
7117        if (stackId == HOME_STACK_ID) {
7118            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7119                    new RuntimeException("here").fillInStackTrace());
7120        }
7121        synchronized (this) {
7122            long ident = Binder.clearCallingIdentity();
7123            try {
7124                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7125                        + stackId + " toTop=" + toTop);
7126                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7127            } finally {
7128                Binder.restoreCallingIdentity(ident);
7129            }
7130        }
7131    }
7132
7133    @Override
7134    public void resizeStack(int stackBoxId, Rect bounds) {
7135        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7136                "resizeStackBox()");
7137        long ident = Binder.clearCallingIdentity();
7138        try {
7139            mWindowManager.resizeStack(stackBoxId, bounds);
7140        } finally {
7141            Binder.restoreCallingIdentity(ident);
7142        }
7143    }
7144
7145    @Override
7146    public List<StackInfo> getAllStackInfos() {
7147        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7148                "getAllStackInfos()");
7149        long ident = Binder.clearCallingIdentity();
7150        try {
7151            synchronized (this) {
7152                return mStackSupervisor.getAllStackInfosLocked();
7153            }
7154        } finally {
7155            Binder.restoreCallingIdentity(ident);
7156        }
7157    }
7158
7159    @Override
7160    public StackInfo getStackInfo(int stackId) {
7161        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7162                "getStackInfo()");
7163        long ident = Binder.clearCallingIdentity();
7164        try {
7165            synchronized (this) {
7166                return mStackSupervisor.getStackInfoLocked(stackId);
7167            }
7168        } finally {
7169            Binder.restoreCallingIdentity(ident);
7170        }
7171    }
7172
7173    @Override
7174    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7175        synchronized(this) {
7176            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7177        }
7178    }
7179
7180    // =========================================================
7181    // THUMBNAILS
7182    // =========================================================
7183
7184    public void reportThumbnail(IBinder token,
7185            Bitmap thumbnail, CharSequence description) {
7186        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7187        final long origId = Binder.clearCallingIdentity();
7188        sendPendingThumbnail(null, token, thumbnail, description, true);
7189        Binder.restoreCallingIdentity(origId);
7190    }
7191
7192    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7193            Bitmap thumbnail, CharSequence description, boolean always) {
7194        TaskRecord task;
7195        ArrayList<PendingThumbnailsRecord> receivers = null;
7196
7197        //System.out.println("Send pending thumbnail: " + r);
7198
7199        synchronized(this) {
7200            if (r == null) {
7201                r = ActivityRecord.isInStackLocked(token);
7202                if (r == null) {
7203                    return;
7204                }
7205            }
7206            if (thumbnail == null && r.thumbHolder != null) {
7207                thumbnail = r.thumbHolder.lastThumbnail;
7208                description = r.thumbHolder.lastDescription;
7209            }
7210            if (thumbnail == null && !always) {
7211                // If there is no thumbnail, and this entry is not actually
7212                // going away, then abort for now and pick up the next
7213                // thumbnail we get.
7214                return;
7215            }
7216            task = r.task;
7217
7218            int N = mPendingThumbnails.size();
7219            int i=0;
7220            while (i<N) {
7221                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7222                //System.out.println("Looking in " + pr.pendingRecords);
7223                if (pr.pendingRecords.remove(r)) {
7224                    if (receivers == null) {
7225                        receivers = new ArrayList<PendingThumbnailsRecord>();
7226                    }
7227                    receivers.add(pr);
7228                    if (pr.pendingRecords.size() == 0) {
7229                        pr.finished = true;
7230                        mPendingThumbnails.remove(i);
7231                        N--;
7232                        continue;
7233                    }
7234                }
7235                i++;
7236            }
7237        }
7238
7239        if (receivers != null) {
7240            final int N = receivers.size();
7241            for (int i=0; i<N; i++) {
7242                try {
7243                    PendingThumbnailsRecord pr = receivers.get(i);
7244                    pr.receiver.newThumbnail(
7245                        task != null ? task.taskId : -1, thumbnail, description);
7246                    if (pr.finished) {
7247                        pr.receiver.finished();
7248                    }
7249                } catch (Exception e) {
7250                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7251                }
7252            }
7253        }
7254    }
7255
7256    // =========================================================
7257    // CONTENT PROVIDERS
7258    // =========================================================
7259
7260    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7261        List<ProviderInfo> providers = null;
7262        try {
7263            providers = AppGlobals.getPackageManager().
7264                queryContentProviders(app.processName, app.uid,
7265                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7266        } catch (RemoteException ex) {
7267        }
7268        if (DEBUG_MU)
7269            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7270        int userId = app.userId;
7271        if (providers != null) {
7272            int N = providers.size();
7273            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7274            for (int i=0; i<N; i++) {
7275                ProviderInfo cpi =
7276                    (ProviderInfo)providers.get(i);
7277                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7278                        cpi.name, cpi.flags);
7279                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7280                    // This is a singleton provider, but a user besides the
7281                    // default user is asking to initialize a process it runs
7282                    // in...  well, no, it doesn't actually run in this process,
7283                    // it runs in the process of the default user.  Get rid of it.
7284                    providers.remove(i);
7285                    N--;
7286                    i--;
7287                    continue;
7288                }
7289
7290                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7291                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7292                if (cpr == null) {
7293                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7294                    mProviderMap.putProviderByClass(comp, cpr);
7295                }
7296                if (DEBUG_MU)
7297                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7298                app.pubProviders.put(cpi.name, cpr);
7299                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7300                    // Don't add this if it is a platform component that is marked
7301                    // to run in multiple processes, because this is actually
7302                    // part of the framework so doesn't make sense to track as a
7303                    // separate apk in the process.
7304                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7305                }
7306                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7307            }
7308        }
7309        return providers;
7310    }
7311
7312    /**
7313     * Check if {@link ProcessRecord} has a possible chance at accessing the
7314     * given {@link ProviderInfo}. Final permission checking is always done
7315     * in {@link ContentProvider}.
7316     */
7317    private final String checkContentProviderPermissionLocked(
7318            ProviderInfo cpi, ProcessRecord r) {
7319        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7320        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7321        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7322                cpi.applicationInfo.uid, cpi.exported)
7323                == PackageManager.PERMISSION_GRANTED) {
7324            return null;
7325        }
7326        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7327                cpi.applicationInfo.uid, cpi.exported)
7328                == PackageManager.PERMISSION_GRANTED) {
7329            return null;
7330        }
7331
7332        PathPermission[] pps = cpi.pathPermissions;
7333        if (pps != null) {
7334            int i = pps.length;
7335            while (i > 0) {
7336                i--;
7337                PathPermission pp = pps[i];
7338                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7339                        cpi.applicationInfo.uid, cpi.exported)
7340                        == PackageManager.PERMISSION_GRANTED) {
7341                    return null;
7342                }
7343                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7344                        cpi.applicationInfo.uid, cpi.exported)
7345                        == PackageManager.PERMISSION_GRANTED) {
7346                    return null;
7347                }
7348            }
7349        }
7350
7351        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7352        if (perms != null) {
7353            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7354                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7355                    return null;
7356                }
7357            }
7358        }
7359
7360        String msg;
7361        if (!cpi.exported) {
7362            msg = "Permission Denial: opening provider " + cpi.name
7363                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7364                    + ", uid=" + callingUid + ") that is not exported from uid "
7365                    + cpi.applicationInfo.uid;
7366        } else {
7367            msg = "Permission Denial: opening provider " + cpi.name
7368                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7369                    + ", uid=" + callingUid + ") requires "
7370                    + cpi.readPermission + " or " + cpi.writePermission;
7371        }
7372        Slog.w(TAG, msg);
7373        return msg;
7374    }
7375
7376    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7377            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7378        if (r != null) {
7379            for (int i=0; i<r.conProviders.size(); i++) {
7380                ContentProviderConnection conn = r.conProviders.get(i);
7381                if (conn.provider == cpr) {
7382                    if (DEBUG_PROVIDER) Slog.v(TAG,
7383                            "Adding provider requested by "
7384                            + r.processName + " from process "
7385                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7386                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7387                    if (stable) {
7388                        conn.stableCount++;
7389                        conn.numStableIncs++;
7390                    } else {
7391                        conn.unstableCount++;
7392                        conn.numUnstableIncs++;
7393                    }
7394                    return conn;
7395                }
7396            }
7397            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7398            if (stable) {
7399                conn.stableCount = 1;
7400                conn.numStableIncs = 1;
7401            } else {
7402                conn.unstableCount = 1;
7403                conn.numUnstableIncs = 1;
7404            }
7405            cpr.connections.add(conn);
7406            r.conProviders.add(conn);
7407            return conn;
7408        }
7409        cpr.addExternalProcessHandleLocked(externalProcessToken);
7410        return null;
7411    }
7412
7413    boolean decProviderCountLocked(ContentProviderConnection conn,
7414            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7415        if (conn != null) {
7416            cpr = conn.provider;
7417            if (DEBUG_PROVIDER) Slog.v(TAG,
7418                    "Removing provider requested by "
7419                    + conn.client.processName + " from process "
7420                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7421                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7422            if (stable) {
7423                conn.stableCount--;
7424            } else {
7425                conn.unstableCount--;
7426            }
7427            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7428                cpr.connections.remove(conn);
7429                conn.client.conProviders.remove(conn);
7430                return true;
7431            }
7432            return false;
7433        }
7434        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7435        return false;
7436    }
7437
7438    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7439            String name, IBinder token, boolean stable, int userId) {
7440        ContentProviderRecord cpr;
7441        ContentProviderConnection conn = null;
7442        ProviderInfo cpi = null;
7443
7444        synchronized(this) {
7445            ProcessRecord r = null;
7446            if (caller != null) {
7447                r = getRecordForAppLocked(caller);
7448                if (r == null) {
7449                    throw new SecurityException(
7450                            "Unable to find app for caller " + caller
7451                          + " (pid=" + Binder.getCallingPid()
7452                          + ") when getting content provider " + name);
7453                }
7454            }
7455
7456            // First check if this content provider has been published...
7457            cpr = mProviderMap.getProviderByName(name, userId);
7458            boolean providerRunning = cpr != null;
7459            if (providerRunning) {
7460                cpi = cpr.info;
7461                String msg;
7462                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7463                    throw new SecurityException(msg);
7464                }
7465
7466                if (r != null && cpr.canRunHere(r)) {
7467                    // This provider has been published or is in the process
7468                    // of being published...  but it is also allowed to run
7469                    // in the caller's process, so don't make a connection
7470                    // and just let the caller instantiate its own instance.
7471                    ContentProviderHolder holder = cpr.newHolder(null);
7472                    // don't give caller the provider object, it needs
7473                    // to make its own.
7474                    holder.provider = null;
7475                    return holder;
7476                }
7477
7478                final long origId = Binder.clearCallingIdentity();
7479
7480                // In this case the provider instance already exists, so we can
7481                // return it right away.
7482                conn = incProviderCountLocked(r, cpr, token, stable);
7483                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7484                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7485                        // If this is a perceptible app accessing the provider,
7486                        // make sure to count it as being accessed and thus
7487                        // back up on the LRU list.  This is good because
7488                        // content providers are often expensive to start.
7489                        updateLruProcessLocked(cpr.proc, false, null);
7490                    }
7491                }
7492
7493                if (cpr.proc != null) {
7494                    if (false) {
7495                        if (cpr.name.flattenToShortString().equals(
7496                                "com.android.providers.calendar/.CalendarProvider2")) {
7497                            Slog.v(TAG, "****************** KILLING "
7498                                + cpr.name.flattenToShortString());
7499                            Process.killProcess(cpr.proc.pid);
7500                        }
7501                    }
7502                    boolean success = updateOomAdjLocked(cpr.proc);
7503                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7504                    // NOTE: there is still a race here where a signal could be
7505                    // pending on the process even though we managed to update its
7506                    // adj level.  Not sure what to do about this, but at least
7507                    // the race is now smaller.
7508                    if (!success) {
7509                        // Uh oh...  it looks like the provider's process
7510                        // has been killed on us.  We need to wait for a new
7511                        // process to be started, and make sure its death
7512                        // doesn't kill our process.
7513                        Slog.i(TAG,
7514                                "Existing provider " + cpr.name.flattenToShortString()
7515                                + " is crashing; detaching " + r);
7516                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7517                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7518                        if (!lastRef) {
7519                            // This wasn't the last ref our process had on
7520                            // the provider...  we have now been killed, bail.
7521                            return null;
7522                        }
7523                        providerRunning = false;
7524                        conn = null;
7525                    }
7526                }
7527
7528                Binder.restoreCallingIdentity(origId);
7529            }
7530
7531            boolean singleton;
7532            if (!providerRunning) {
7533                try {
7534                    cpi = AppGlobals.getPackageManager().
7535                        resolveContentProvider(name,
7536                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7537                } catch (RemoteException ex) {
7538                }
7539                if (cpi == null) {
7540                    return null;
7541                }
7542                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7543                        cpi.name, cpi.flags);
7544                if (singleton) {
7545                    userId = 0;
7546                }
7547                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7548
7549                String msg;
7550                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7551                    throw new SecurityException(msg);
7552                }
7553
7554                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7555                        && !cpi.processName.equals("system")) {
7556                    // If this content provider does not run in the system
7557                    // process, and the system is not yet ready to run other
7558                    // processes, then fail fast instead of hanging.
7559                    throw new IllegalArgumentException(
7560                            "Attempt to launch content provider before system ready");
7561                }
7562
7563                // Make sure that the user who owns this provider is started.  If not,
7564                // we don't want to allow it to run.
7565                if (mStartedUsers.get(userId) == null) {
7566                    Slog.w(TAG, "Unable to launch app "
7567                            + cpi.applicationInfo.packageName + "/"
7568                            + cpi.applicationInfo.uid + " for provider "
7569                            + name + ": user " + userId + " is stopped");
7570                    return null;
7571                }
7572
7573                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7574                cpr = mProviderMap.getProviderByClass(comp, userId);
7575                final boolean firstClass = cpr == null;
7576                if (firstClass) {
7577                    try {
7578                        ApplicationInfo ai =
7579                            AppGlobals.getPackageManager().
7580                                getApplicationInfo(
7581                                        cpi.applicationInfo.packageName,
7582                                        STOCK_PM_FLAGS, userId);
7583                        if (ai == null) {
7584                            Slog.w(TAG, "No package info for content provider "
7585                                    + cpi.name);
7586                            return null;
7587                        }
7588                        ai = getAppInfoForUser(ai, userId);
7589                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7590                    } catch (RemoteException ex) {
7591                        // pm is in same process, this will never happen.
7592                    }
7593                }
7594
7595                if (r != null && cpr.canRunHere(r)) {
7596                    // If this is a multiprocess provider, then just return its
7597                    // info and allow the caller to instantiate it.  Only do
7598                    // this if the provider is the same user as the caller's
7599                    // process, or can run as root (so can be in any process).
7600                    return cpr.newHolder(null);
7601                }
7602
7603                if (DEBUG_PROVIDER) {
7604                    RuntimeException e = new RuntimeException("here");
7605                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7606                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7607                }
7608
7609                // This is single process, and our app is now connecting to it.
7610                // See if we are already in the process of launching this
7611                // provider.
7612                final int N = mLaunchingProviders.size();
7613                int i;
7614                for (i=0; i<N; i++) {
7615                    if (mLaunchingProviders.get(i) == cpr) {
7616                        break;
7617                    }
7618                }
7619
7620                // If the provider is not already being launched, then get it
7621                // started.
7622                if (i >= N) {
7623                    final long origId = Binder.clearCallingIdentity();
7624
7625                    try {
7626                        // Content provider is now in use, its package can't be stopped.
7627                        try {
7628                            AppGlobals.getPackageManager().setPackageStoppedState(
7629                                    cpr.appInfo.packageName, false, userId);
7630                        } catch (RemoteException e) {
7631                        } catch (IllegalArgumentException e) {
7632                            Slog.w(TAG, "Failed trying to unstop package "
7633                                    + cpr.appInfo.packageName + ": " + e);
7634                        }
7635
7636                        // Use existing process if already started
7637                        ProcessRecord proc = getProcessRecordLocked(
7638                                cpi.processName, cpr.appInfo.uid, false);
7639                        if (proc != null && proc.thread != null) {
7640                            if (DEBUG_PROVIDER) {
7641                                Slog.d(TAG, "Installing in existing process " + proc);
7642                            }
7643                            proc.pubProviders.put(cpi.name, cpr);
7644                            try {
7645                                proc.thread.scheduleInstallProvider(cpi);
7646                            } catch (RemoteException e) {
7647                            }
7648                        } else {
7649                            proc = startProcessLocked(cpi.processName,
7650                                    cpr.appInfo, false, 0, "content provider",
7651                                    new ComponentName(cpi.applicationInfo.packageName,
7652                                            cpi.name), false, false, false);
7653                            if (proc == null) {
7654                                Slog.w(TAG, "Unable to launch app "
7655                                        + cpi.applicationInfo.packageName + "/"
7656                                        + cpi.applicationInfo.uid + " for provider "
7657                                        + name + ": process is bad");
7658                                return null;
7659                            }
7660                        }
7661                        cpr.launchingApp = proc;
7662                        mLaunchingProviders.add(cpr);
7663                    } finally {
7664                        Binder.restoreCallingIdentity(origId);
7665                    }
7666                }
7667
7668                // Make sure the provider is published (the same provider class
7669                // may be published under multiple names).
7670                if (firstClass) {
7671                    mProviderMap.putProviderByClass(comp, cpr);
7672                }
7673
7674                mProviderMap.putProviderByName(name, cpr);
7675                conn = incProviderCountLocked(r, cpr, token, stable);
7676                if (conn != null) {
7677                    conn.waiting = true;
7678                }
7679            }
7680        }
7681
7682        // Wait for the provider to be published...
7683        synchronized (cpr) {
7684            while (cpr.provider == null) {
7685                if (cpr.launchingApp == null) {
7686                    Slog.w(TAG, "Unable to launch app "
7687                            + cpi.applicationInfo.packageName + "/"
7688                            + cpi.applicationInfo.uid + " for provider "
7689                            + name + ": launching app became null");
7690                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7691                            UserHandle.getUserId(cpi.applicationInfo.uid),
7692                            cpi.applicationInfo.packageName,
7693                            cpi.applicationInfo.uid, name);
7694                    return null;
7695                }
7696                try {
7697                    if (DEBUG_MU) {
7698                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7699                                + cpr.launchingApp);
7700                    }
7701                    if (conn != null) {
7702                        conn.waiting = true;
7703                    }
7704                    cpr.wait();
7705                } catch (InterruptedException ex) {
7706                } finally {
7707                    if (conn != null) {
7708                        conn.waiting = false;
7709                    }
7710                }
7711            }
7712        }
7713        return cpr != null ? cpr.newHolder(conn) : null;
7714    }
7715
7716    public final ContentProviderHolder getContentProvider(
7717            IApplicationThread caller, String name, int userId, boolean stable) {
7718        enforceNotIsolatedCaller("getContentProvider");
7719        if (caller == null) {
7720            String msg = "null IApplicationThread when getting content provider "
7721                    + name;
7722            Slog.w(TAG, msg);
7723            throw new SecurityException(msg);
7724        }
7725
7726        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7727                false, true, "getContentProvider", null);
7728        return getContentProviderImpl(caller, name, null, stable, userId);
7729    }
7730
7731    public ContentProviderHolder getContentProviderExternal(
7732            String name, int userId, IBinder token) {
7733        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7734            "Do not have permission in call getContentProviderExternal()");
7735        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7736                false, true, "getContentProvider", null);
7737        return getContentProviderExternalUnchecked(name, token, userId);
7738    }
7739
7740    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7741            IBinder token, int userId) {
7742        return getContentProviderImpl(null, name, token, true, userId);
7743    }
7744
7745    /**
7746     * Drop a content provider from a ProcessRecord's bookkeeping
7747     */
7748    public void removeContentProvider(IBinder connection, boolean stable) {
7749        enforceNotIsolatedCaller("removeContentProvider");
7750        synchronized (this) {
7751            ContentProviderConnection conn;
7752            try {
7753                conn = (ContentProviderConnection)connection;
7754            } catch (ClassCastException e) {
7755                String msg ="removeContentProvider: " + connection
7756                        + " not a ContentProviderConnection";
7757                Slog.w(TAG, msg);
7758                throw new IllegalArgumentException(msg);
7759            }
7760            if (conn == null) {
7761                throw new NullPointerException("connection is null");
7762            }
7763            if (decProviderCountLocked(conn, null, null, stable)) {
7764                updateOomAdjLocked();
7765            }
7766        }
7767    }
7768
7769    public void removeContentProviderExternal(String name, IBinder token) {
7770        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7771            "Do not have permission in call removeContentProviderExternal()");
7772        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7773    }
7774
7775    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7776        synchronized (this) {
7777            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7778            if(cpr == null) {
7779                //remove from mProvidersByClass
7780                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7781                return;
7782            }
7783
7784            //update content provider record entry info
7785            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7786            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7787            if (localCpr.hasExternalProcessHandles()) {
7788                if (localCpr.removeExternalProcessHandleLocked(token)) {
7789                    updateOomAdjLocked();
7790                } else {
7791                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7792                            + " with no external reference for token: "
7793                            + token + ".");
7794                }
7795            } else {
7796                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7797                        + " with no external references.");
7798            }
7799        }
7800    }
7801
7802    public final void publishContentProviders(IApplicationThread caller,
7803            List<ContentProviderHolder> providers) {
7804        if (providers == null) {
7805            return;
7806        }
7807
7808        enforceNotIsolatedCaller("publishContentProviders");
7809        synchronized (this) {
7810            final ProcessRecord r = getRecordForAppLocked(caller);
7811            if (DEBUG_MU)
7812                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7813            if (r == null) {
7814                throw new SecurityException(
7815                        "Unable to find app for caller " + caller
7816                      + " (pid=" + Binder.getCallingPid()
7817                      + ") when publishing content providers");
7818            }
7819
7820            final long origId = Binder.clearCallingIdentity();
7821
7822            final int N = providers.size();
7823            for (int i=0; i<N; i++) {
7824                ContentProviderHolder src = providers.get(i);
7825                if (src == null || src.info == null || src.provider == null) {
7826                    continue;
7827                }
7828                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7829                if (DEBUG_MU)
7830                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7831                if (dst != null) {
7832                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7833                    mProviderMap.putProviderByClass(comp, dst);
7834                    String names[] = dst.info.authority.split(";");
7835                    for (int j = 0; j < names.length; j++) {
7836                        mProviderMap.putProviderByName(names[j], dst);
7837                    }
7838
7839                    int NL = mLaunchingProviders.size();
7840                    int j;
7841                    for (j=0; j<NL; j++) {
7842                        if (mLaunchingProviders.get(j) == dst) {
7843                            mLaunchingProviders.remove(j);
7844                            j--;
7845                            NL--;
7846                        }
7847                    }
7848                    synchronized (dst) {
7849                        dst.provider = src.provider;
7850                        dst.proc = r;
7851                        dst.notifyAll();
7852                    }
7853                    updateOomAdjLocked(r);
7854                }
7855            }
7856
7857            Binder.restoreCallingIdentity(origId);
7858        }
7859    }
7860
7861    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7862        ContentProviderConnection conn;
7863        try {
7864            conn = (ContentProviderConnection)connection;
7865        } catch (ClassCastException e) {
7866            String msg ="refContentProvider: " + connection
7867                    + " not a ContentProviderConnection";
7868            Slog.w(TAG, msg);
7869            throw new IllegalArgumentException(msg);
7870        }
7871        if (conn == null) {
7872            throw new NullPointerException("connection is null");
7873        }
7874
7875        synchronized (this) {
7876            if (stable > 0) {
7877                conn.numStableIncs += stable;
7878            }
7879            stable = conn.stableCount + stable;
7880            if (stable < 0) {
7881                throw new IllegalStateException("stableCount < 0: " + stable);
7882            }
7883
7884            if (unstable > 0) {
7885                conn.numUnstableIncs += unstable;
7886            }
7887            unstable = conn.unstableCount + unstable;
7888            if (unstable < 0) {
7889                throw new IllegalStateException("unstableCount < 0: " + unstable);
7890            }
7891
7892            if ((stable+unstable) <= 0) {
7893                throw new IllegalStateException("ref counts can't go to zero here: stable="
7894                        + stable + " unstable=" + unstable);
7895            }
7896            conn.stableCount = stable;
7897            conn.unstableCount = unstable;
7898            return !conn.dead;
7899        }
7900    }
7901
7902    public void unstableProviderDied(IBinder connection) {
7903        ContentProviderConnection conn;
7904        try {
7905            conn = (ContentProviderConnection)connection;
7906        } catch (ClassCastException e) {
7907            String msg ="refContentProvider: " + connection
7908                    + " not a ContentProviderConnection";
7909            Slog.w(TAG, msg);
7910            throw new IllegalArgumentException(msg);
7911        }
7912        if (conn == null) {
7913            throw new NullPointerException("connection is null");
7914        }
7915
7916        // Safely retrieve the content provider associated with the connection.
7917        IContentProvider provider;
7918        synchronized (this) {
7919            provider = conn.provider.provider;
7920        }
7921
7922        if (provider == null) {
7923            // Um, yeah, we're way ahead of you.
7924            return;
7925        }
7926
7927        // Make sure the caller is being honest with us.
7928        if (provider.asBinder().pingBinder()) {
7929            // Er, no, still looks good to us.
7930            synchronized (this) {
7931                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7932                        + " says " + conn + " died, but we don't agree");
7933                return;
7934            }
7935        }
7936
7937        // Well look at that!  It's dead!
7938        synchronized (this) {
7939            if (conn.provider.provider != provider) {
7940                // But something changed...  good enough.
7941                return;
7942            }
7943
7944            ProcessRecord proc = conn.provider.proc;
7945            if (proc == null || proc.thread == null) {
7946                // Seems like the process is already cleaned up.
7947                return;
7948            }
7949
7950            // As far as we're concerned, this is just like receiving a
7951            // death notification...  just a bit prematurely.
7952            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7953                    + ") early provider death");
7954            final long ident = Binder.clearCallingIdentity();
7955            try {
7956                appDiedLocked(proc, proc.pid, proc.thread);
7957            } finally {
7958                Binder.restoreCallingIdentity(ident);
7959            }
7960        }
7961    }
7962
7963    @Override
7964    public void appNotRespondingViaProvider(IBinder connection) {
7965        enforceCallingPermission(
7966                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7967
7968        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7969        if (conn == null) {
7970            Slog.w(TAG, "ContentProviderConnection is null");
7971            return;
7972        }
7973
7974        final ProcessRecord host = conn.provider.proc;
7975        if (host == null) {
7976            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7977            return;
7978        }
7979
7980        final long token = Binder.clearCallingIdentity();
7981        try {
7982            appNotResponding(host, null, null, false, "ContentProvider not responding");
7983        } finally {
7984            Binder.restoreCallingIdentity(token);
7985        }
7986    }
7987
7988    public static final void installSystemProviders() {
7989        List<ProviderInfo> providers;
7990        synchronized (sSelf) {
7991            ProcessRecord app = sSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7992            providers = sSelf.generateApplicationProvidersLocked(app);
7993            if (providers != null) {
7994                for (int i=providers.size()-1; i>=0; i--) {
7995                    ProviderInfo pi = (ProviderInfo)providers.get(i);
7996                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7997                        Slog.w(TAG, "Not installing system proc provider " + pi.name
7998                                + ": not system .apk");
7999                        providers.remove(i);
8000                    }
8001                }
8002            }
8003        }
8004        if (providers != null) {
8005            sSystemThread.installSystemProviders(providers);
8006        }
8007
8008        sSelf.mCoreSettingsObserver = new CoreSettingsObserver(sSelf);
8009
8010        sSelf.mUsageStatsService.monitorPackages();
8011    }
8012
8013    /**
8014     * Allows app to retrieve the MIME type of a URI without having permission
8015     * to access its content provider.
8016     *
8017     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8018     *
8019     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8020     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8021     */
8022    public String getProviderMimeType(Uri uri, int userId) {
8023        enforceNotIsolatedCaller("getProviderMimeType");
8024        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8025                userId, false, true, "getProviderMimeType", null);
8026        final String name = uri.getAuthority();
8027        final long ident = Binder.clearCallingIdentity();
8028        ContentProviderHolder holder = null;
8029
8030        try {
8031            holder = getContentProviderExternalUnchecked(name, null, userId);
8032            if (holder != null) {
8033                return holder.provider.getType(uri);
8034            }
8035        } catch (RemoteException e) {
8036            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8037            return null;
8038        } finally {
8039            if (holder != null) {
8040                removeContentProviderExternalUnchecked(name, null, userId);
8041            }
8042            Binder.restoreCallingIdentity(ident);
8043        }
8044
8045        return null;
8046    }
8047
8048    // =========================================================
8049    // GLOBAL MANAGEMENT
8050    // =========================================================
8051
8052    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8053            boolean isolated) {
8054        String proc = customProcess != null ? customProcess : info.processName;
8055        BatteryStatsImpl.Uid.Proc ps = null;
8056        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8057        int uid = info.uid;
8058        if (isolated) {
8059            int userId = UserHandle.getUserId(uid);
8060            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8061            while (true) {
8062                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8063                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8064                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8065                }
8066                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8067                mNextIsolatedProcessUid++;
8068                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8069                    // No process for this uid, use it.
8070                    break;
8071                }
8072                stepsLeft--;
8073                if (stepsLeft <= 0) {
8074                    return null;
8075                }
8076            }
8077        }
8078        return new ProcessRecord(stats, info, proc, uid);
8079    }
8080
8081    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8082        ProcessRecord app;
8083        if (!isolated) {
8084            app = getProcessRecordLocked(info.processName, info.uid, true);
8085        } else {
8086            app = null;
8087        }
8088
8089        if (app == null) {
8090            app = newProcessRecordLocked(info, null, isolated);
8091            mProcessNames.put(info.processName, app.uid, app);
8092            if (isolated) {
8093                mIsolatedProcesses.put(app.uid, app);
8094            }
8095            updateLruProcessLocked(app, false, null);
8096            updateOomAdjLocked();
8097        }
8098
8099        // This package really, really can not be stopped.
8100        try {
8101            AppGlobals.getPackageManager().setPackageStoppedState(
8102                    info.packageName, false, UserHandle.getUserId(app.uid));
8103        } catch (RemoteException e) {
8104        } catch (IllegalArgumentException e) {
8105            Slog.w(TAG, "Failed trying to unstop package "
8106                    + info.packageName + ": " + e);
8107        }
8108
8109        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8110                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8111            app.persistent = true;
8112            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8113        }
8114        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8115            mPersistentStartingProcesses.add(app);
8116            startProcessLocked(app, "added application", app.processName);
8117        }
8118
8119        return app;
8120    }
8121
8122    public void unhandledBack() {
8123        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8124                "unhandledBack()");
8125
8126        synchronized(this) {
8127            final long origId = Binder.clearCallingIdentity();
8128            try {
8129                getFocusedStack().unhandledBackLocked();
8130            } finally {
8131                Binder.restoreCallingIdentity(origId);
8132            }
8133        }
8134    }
8135
8136    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8137        enforceNotIsolatedCaller("openContentUri");
8138        final int userId = UserHandle.getCallingUserId();
8139        String name = uri.getAuthority();
8140        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8141        ParcelFileDescriptor pfd = null;
8142        if (cph != null) {
8143            // We record the binder invoker's uid in thread-local storage before
8144            // going to the content provider to open the file.  Later, in the code
8145            // that handles all permissions checks, we look for this uid and use
8146            // that rather than the Activity Manager's own uid.  The effect is that
8147            // we do the check against the caller's permissions even though it looks
8148            // to the content provider like the Activity Manager itself is making
8149            // the request.
8150            sCallerIdentity.set(new Identity(
8151                    Binder.getCallingPid(), Binder.getCallingUid()));
8152            try {
8153                pfd = cph.provider.openFile(null, uri, "r", null);
8154            } catch (FileNotFoundException e) {
8155                // do nothing; pfd will be returned null
8156            } finally {
8157                // Ensure that whatever happens, we clean up the identity state
8158                sCallerIdentity.remove();
8159            }
8160
8161            // We've got the fd now, so we're done with the provider.
8162            removeContentProviderExternalUnchecked(name, null, userId);
8163        } else {
8164            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8165        }
8166        return pfd;
8167    }
8168
8169    // Actually is sleeping or shutting down or whatever else in the future
8170    // is an inactive state.
8171    public boolean isSleepingOrShuttingDown() {
8172        return mSleeping || mShuttingDown;
8173    }
8174
8175    public void goingToSleep() {
8176        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8177                != PackageManager.PERMISSION_GRANTED) {
8178            throw new SecurityException("Requires permission "
8179                    + android.Manifest.permission.DEVICE_POWER);
8180        }
8181
8182        synchronized(this) {
8183            mWentToSleep = true;
8184            updateEventDispatchingLocked();
8185
8186            if (!mSleeping) {
8187                mSleeping = true;
8188                mStackSupervisor.goingToSleepLocked();
8189
8190                // Initialize the wake times of all processes.
8191                checkExcessivePowerUsageLocked(false);
8192                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8193                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8194                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8195            }
8196        }
8197    }
8198
8199    @Override
8200    public boolean shutdown(int timeout) {
8201        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8202                != PackageManager.PERMISSION_GRANTED) {
8203            throw new SecurityException("Requires permission "
8204                    + android.Manifest.permission.SHUTDOWN);
8205        }
8206
8207        boolean timedout = false;
8208
8209        synchronized(this) {
8210            mShuttingDown = true;
8211            updateEventDispatchingLocked();
8212            timedout = mStackSupervisor.shutdownLocked(timeout);
8213        }
8214
8215        mAppOpsService.shutdown();
8216        mUsageStatsService.shutdown();
8217        mBatteryStatsService.shutdown();
8218        synchronized (this) {
8219            mProcessStats.shutdownLocked();
8220        }
8221
8222        return timedout;
8223    }
8224
8225    public final void activitySlept(IBinder token) {
8226        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8227
8228        final long origId = Binder.clearCallingIdentity();
8229
8230        synchronized (this) {
8231            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8232            if (r != null) {
8233                mStackSupervisor.activitySleptLocked(r);
8234            }
8235        }
8236
8237        Binder.restoreCallingIdentity(origId);
8238    }
8239
8240    void logLockScreen(String msg) {
8241        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8242                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8243                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8244                mStackSupervisor.mDismissKeyguardOnNextActivity);
8245    }
8246
8247    private void comeOutOfSleepIfNeededLocked() {
8248        if (!mWentToSleep && !mLockScreenShown) {
8249            if (mSleeping) {
8250                mSleeping = false;
8251                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8252            }
8253        }
8254    }
8255
8256    public void wakingUp() {
8257        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8258                != PackageManager.PERMISSION_GRANTED) {
8259            throw new SecurityException("Requires permission "
8260                    + android.Manifest.permission.DEVICE_POWER);
8261        }
8262
8263        synchronized(this) {
8264            mWentToSleep = false;
8265            updateEventDispatchingLocked();
8266            comeOutOfSleepIfNeededLocked();
8267        }
8268    }
8269
8270    private void updateEventDispatchingLocked() {
8271        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8272    }
8273
8274    public void setLockScreenShown(boolean shown) {
8275        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8276                != PackageManager.PERMISSION_GRANTED) {
8277            throw new SecurityException("Requires permission "
8278                    + android.Manifest.permission.DEVICE_POWER);
8279        }
8280
8281        synchronized(this) {
8282            long ident = Binder.clearCallingIdentity();
8283            try {
8284                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8285                mLockScreenShown = shown;
8286                comeOutOfSleepIfNeededLocked();
8287            } finally {
8288                Binder.restoreCallingIdentity(ident);
8289            }
8290        }
8291    }
8292
8293    public void stopAppSwitches() {
8294        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8295                != PackageManager.PERMISSION_GRANTED) {
8296            throw new SecurityException("Requires permission "
8297                    + android.Manifest.permission.STOP_APP_SWITCHES);
8298        }
8299
8300        synchronized(this) {
8301            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8302                    + APP_SWITCH_DELAY_TIME;
8303            mDidAppSwitch = false;
8304            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8305            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8306            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8307        }
8308    }
8309
8310    public void resumeAppSwitches() {
8311        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8312                != PackageManager.PERMISSION_GRANTED) {
8313            throw new SecurityException("Requires permission "
8314                    + android.Manifest.permission.STOP_APP_SWITCHES);
8315        }
8316
8317        synchronized(this) {
8318            // Note that we don't execute any pending app switches... we will
8319            // let those wait until either the timeout, or the next start
8320            // activity request.
8321            mAppSwitchesAllowedTime = 0;
8322        }
8323    }
8324
8325    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8326            String name) {
8327        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8328            return true;
8329        }
8330
8331        final int perm = checkComponentPermission(
8332                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8333                callingUid, -1, true);
8334        if (perm == PackageManager.PERMISSION_GRANTED) {
8335            return true;
8336        }
8337
8338        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8339        return false;
8340    }
8341
8342    public void setDebugApp(String packageName, boolean waitForDebugger,
8343            boolean persistent) {
8344        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8345                "setDebugApp()");
8346
8347        long ident = Binder.clearCallingIdentity();
8348        try {
8349            // Note that this is not really thread safe if there are multiple
8350            // callers into it at the same time, but that's not a situation we
8351            // care about.
8352            if (persistent) {
8353                final ContentResolver resolver = mContext.getContentResolver();
8354                Settings.Global.putString(
8355                    resolver, Settings.Global.DEBUG_APP,
8356                    packageName);
8357                Settings.Global.putInt(
8358                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8359                    waitForDebugger ? 1 : 0);
8360            }
8361
8362            synchronized (this) {
8363                if (!persistent) {
8364                    mOrigDebugApp = mDebugApp;
8365                    mOrigWaitForDebugger = mWaitForDebugger;
8366                }
8367                mDebugApp = packageName;
8368                mWaitForDebugger = waitForDebugger;
8369                mDebugTransient = !persistent;
8370                if (packageName != null) {
8371                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8372                            false, UserHandle.USER_ALL, "set debug app");
8373                }
8374            }
8375        } finally {
8376            Binder.restoreCallingIdentity(ident);
8377        }
8378    }
8379
8380    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8381        synchronized (this) {
8382            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8383            if (!isDebuggable) {
8384                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8385                    throw new SecurityException("Process not debuggable: " + app.packageName);
8386                }
8387            }
8388
8389            mOpenGlTraceApp = processName;
8390        }
8391    }
8392
8393    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8394            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8395        synchronized (this) {
8396            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8397            if (!isDebuggable) {
8398                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8399                    throw new SecurityException("Process not debuggable: " + app.packageName);
8400                }
8401            }
8402            mProfileApp = processName;
8403            mProfileFile = profileFile;
8404            if (mProfileFd != null) {
8405                try {
8406                    mProfileFd.close();
8407                } catch (IOException e) {
8408                }
8409                mProfileFd = null;
8410            }
8411            mProfileFd = profileFd;
8412            mProfileType = 0;
8413            mAutoStopProfiler = autoStopProfiler;
8414        }
8415    }
8416
8417    @Override
8418    public void setAlwaysFinish(boolean enabled) {
8419        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8420                "setAlwaysFinish()");
8421
8422        Settings.Global.putInt(
8423                mContext.getContentResolver(),
8424                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8425
8426        synchronized (this) {
8427            mAlwaysFinishActivities = enabled;
8428        }
8429    }
8430
8431    @Override
8432    public void setActivityController(IActivityController controller) {
8433        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8434                "setActivityController()");
8435        synchronized (this) {
8436            mController = controller;
8437            Watchdog.getInstance().setActivityController(controller);
8438        }
8439    }
8440
8441    @Override
8442    public void setUserIsMonkey(boolean userIsMonkey) {
8443        synchronized (this) {
8444            synchronized (mPidsSelfLocked) {
8445                final int callingPid = Binder.getCallingPid();
8446                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8447                if (precessRecord == null) {
8448                    throw new SecurityException("Unknown process: " + callingPid);
8449                }
8450                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8451                    throw new SecurityException("Only an instrumentation process "
8452                            + "with a UiAutomation can call setUserIsMonkey");
8453                }
8454            }
8455            mUserIsMonkey = userIsMonkey;
8456        }
8457    }
8458
8459    @Override
8460    public boolean isUserAMonkey() {
8461        synchronized (this) {
8462            // If there is a controller also implies the user is a monkey.
8463            return (mUserIsMonkey || mController != null);
8464        }
8465    }
8466
8467    public void requestBugReport() {
8468        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8469        SystemProperties.set("ctl.start", "bugreport");
8470    }
8471
8472    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8473        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8474    }
8475
8476    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8477        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8478            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8479        }
8480        return KEY_DISPATCHING_TIMEOUT;
8481    }
8482
8483    @Override
8484    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8485        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8486                != PackageManager.PERMISSION_GRANTED) {
8487            throw new SecurityException("Requires permission "
8488                    + android.Manifest.permission.FILTER_EVENTS);
8489        }
8490        ProcessRecord proc;
8491        long timeout;
8492        synchronized (this) {
8493            synchronized (mPidsSelfLocked) {
8494                proc = mPidsSelfLocked.get(pid);
8495            }
8496            timeout = getInputDispatchingTimeoutLocked(proc);
8497        }
8498
8499        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8500            return -1;
8501        }
8502
8503        return timeout;
8504    }
8505
8506    /**
8507     * Handle input dispatching timeouts.
8508     * Returns whether input dispatching should be aborted or not.
8509     */
8510    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8511            final ActivityRecord activity, final ActivityRecord parent,
8512            final boolean aboveSystem, String reason) {
8513        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8514                != PackageManager.PERMISSION_GRANTED) {
8515            throw new SecurityException("Requires permission "
8516                    + android.Manifest.permission.FILTER_EVENTS);
8517        }
8518
8519        final String annotation;
8520        if (reason == null) {
8521            annotation = "Input dispatching timed out";
8522        } else {
8523            annotation = "Input dispatching timed out (" + reason + ")";
8524        }
8525
8526        if (proc != null) {
8527            synchronized (this) {
8528                if (proc.debugging) {
8529                    return false;
8530                }
8531
8532                if (mDidDexOpt) {
8533                    // Give more time since we were dexopting.
8534                    mDidDexOpt = false;
8535                    return false;
8536                }
8537
8538                if (proc.instrumentationClass != null) {
8539                    Bundle info = new Bundle();
8540                    info.putString("shortMsg", "keyDispatchingTimedOut");
8541                    info.putString("longMsg", annotation);
8542                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8543                    return true;
8544                }
8545            }
8546            mHandler.post(new Runnable() {
8547                @Override
8548                public void run() {
8549                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8550                }
8551            });
8552        }
8553
8554        return true;
8555    }
8556
8557    public Bundle getAssistContextExtras(int requestType) {
8558        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8559                "getAssistContextExtras()");
8560        PendingAssistExtras pae;
8561        Bundle extras = new Bundle();
8562        synchronized (this) {
8563            ActivityRecord activity = getFocusedStack().mResumedActivity;
8564            if (activity == null) {
8565                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8566                return null;
8567            }
8568            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8569            if (activity.app == null || activity.app.thread == null) {
8570                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8571                return extras;
8572            }
8573            if (activity.app.pid == Binder.getCallingPid()) {
8574                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8575                return extras;
8576            }
8577            pae = new PendingAssistExtras(activity);
8578            try {
8579                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8580                        requestType);
8581                mPendingAssistExtras.add(pae);
8582                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8583            } catch (RemoteException e) {
8584                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8585                return extras;
8586            }
8587        }
8588        synchronized (pae) {
8589            while (!pae.haveResult) {
8590                try {
8591                    pae.wait();
8592                } catch (InterruptedException e) {
8593                }
8594            }
8595            if (pae.result != null) {
8596                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8597            }
8598        }
8599        synchronized (this) {
8600            mPendingAssistExtras.remove(pae);
8601            mHandler.removeCallbacks(pae);
8602        }
8603        return extras;
8604    }
8605
8606    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8607        PendingAssistExtras pae = (PendingAssistExtras)token;
8608        synchronized (pae) {
8609            pae.result = extras;
8610            pae.haveResult = true;
8611            pae.notifyAll();
8612        }
8613    }
8614
8615    public void registerProcessObserver(IProcessObserver observer) {
8616        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8617                "registerProcessObserver()");
8618        synchronized (this) {
8619            mProcessObservers.register(observer);
8620        }
8621    }
8622
8623    @Override
8624    public void unregisterProcessObserver(IProcessObserver observer) {
8625        synchronized (this) {
8626            mProcessObservers.unregister(observer);
8627        }
8628    }
8629
8630    @Override
8631    public boolean convertFromTranslucent(IBinder token) {
8632        final long origId = Binder.clearCallingIdentity();
8633        try {
8634            synchronized (this) {
8635                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8636                if (r == null) {
8637                    return false;
8638                }
8639                if (r.changeWindowTranslucency(true)) {
8640                    mWindowManager.setAppFullscreen(token, true);
8641                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8642                    return true;
8643                }
8644                return false;
8645            }
8646        } finally {
8647            Binder.restoreCallingIdentity(origId);
8648        }
8649    }
8650
8651    @Override
8652    public boolean convertToTranslucent(IBinder token) {
8653        final long origId = Binder.clearCallingIdentity();
8654        try {
8655            synchronized (this) {
8656                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8657                if (r == null) {
8658                    return false;
8659                }
8660                if (r.changeWindowTranslucency(false)) {
8661                    r.task.stack.convertToTranslucent(r);
8662                    mWindowManager.setAppFullscreen(token, false);
8663                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8664                    return true;
8665                }
8666                return false;
8667            }
8668        } finally {
8669            Binder.restoreCallingIdentity(origId);
8670        }
8671    }
8672
8673    @Override
8674    public void setImmersive(IBinder token, boolean immersive) {
8675        synchronized(this) {
8676            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8677            if (r == null) {
8678                throw new IllegalArgumentException();
8679            }
8680            r.immersive = immersive;
8681
8682            // update associated state if we're frontmost
8683            if (r == mFocusedActivity) {
8684                if (DEBUG_IMMERSIVE) {
8685                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8686                }
8687                applyUpdateLockStateLocked(r);
8688            }
8689        }
8690    }
8691
8692    @Override
8693    public boolean isImmersive(IBinder token) {
8694        synchronized (this) {
8695            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8696            if (r == null) {
8697                throw new IllegalArgumentException();
8698            }
8699            return r.immersive;
8700        }
8701    }
8702
8703    public boolean isTopActivityImmersive() {
8704        enforceNotIsolatedCaller("startActivity");
8705        synchronized (this) {
8706            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8707            return (r != null) ? r.immersive : false;
8708        }
8709    }
8710
8711    public final void enterSafeMode() {
8712        synchronized(this) {
8713            // It only makes sense to do this before the system is ready
8714            // and started launching other packages.
8715            if (!mSystemReady) {
8716                try {
8717                    AppGlobals.getPackageManager().enterSafeMode();
8718                } catch (RemoteException e) {
8719                }
8720            }
8721        }
8722    }
8723
8724    public final void showSafeModeOverlay() {
8725        View v = LayoutInflater.from(mContext).inflate(
8726                com.android.internal.R.layout.safe_mode, null);
8727        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8728        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8729        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8730        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8731        lp.gravity = Gravity.BOTTOM | Gravity.START;
8732        lp.format = v.getBackground().getOpacity();
8733        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8734                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8735        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8736        ((WindowManager)mContext.getSystemService(
8737                Context.WINDOW_SERVICE)).addView(v, lp);
8738    }
8739
8740    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8741        if (!(sender instanceof PendingIntentRecord)) {
8742            return;
8743        }
8744        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8745        synchronized (stats) {
8746            if (mBatteryStatsService.isOnBattery()) {
8747                mBatteryStatsService.enforceCallingPermission();
8748                PendingIntentRecord rec = (PendingIntentRecord)sender;
8749                int MY_UID = Binder.getCallingUid();
8750                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8751                BatteryStatsImpl.Uid.Pkg pkg =
8752                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8753                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8754                pkg.incWakeupsLocked();
8755            }
8756        }
8757    }
8758
8759    public boolean killPids(int[] pids, String pReason, boolean secure) {
8760        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8761            throw new SecurityException("killPids only available to the system");
8762        }
8763        String reason = (pReason == null) ? "Unknown" : pReason;
8764        // XXX Note: don't acquire main activity lock here, because the window
8765        // manager calls in with its locks held.
8766
8767        boolean killed = false;
8768        synchronized (mPidsSelfLocked) {
8769            int[] types = new int[pids.length];
8770            int worstType = 0;
8771            for (int i=0; i<pids.length; i++) {
8772                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8773                if (proc != null) {
8774                    int type = proc.setAdj;
8775                    types[i] = type;
8776                    if (type > worstType) {
8777                        worstType = type;
8778                    }
8779                }
8780            }
8781
8782            // If the worst oom_adj is somewhere in the cached proc LRU range,
8783            // then constrain it so we will kill all cached procs.
8784            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8785                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8786                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8787            }
8788
8789            // If this is not a secure call, don't let it kill processes that
8790            // are important.
8791            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8792                worstType = ProcessList.SERVICE_ADJ;
8793            }
8794
8795            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8796            for (int i=0; i<pids.length; i++) {
8797                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8798                if (proc == null) {
8799                    continue;
8800                }
8801                int adj = proc.setAdj;
8802                if (adj >= worstType && !proc.killedByAm) {
8803                    killUnneededProcessLocked(proc, reason);
8804                    killed = true;
8805                }
8806            }
8807        }
8808        return killed;
8809    }
8810
8811    @Override
8812    public void killUid(int uid, String reason) {
8813        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8814            throw new SecurityException("killUid only available to the system");
8815        }
8816        synchronized (this) {
8817            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8818                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8819                    reason != null ? reason : "kill uid");
8820        }
8821    }
8822
8823    @Override
8824    public boolean killProcessesBelowForeground(String reason) {
8825        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8826            throw new SecurityException("killProcessesBelowForeground() only available to system");
8827        }
8828
8829        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8830    }
8831
8832    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8833        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8834            throw new SecurityException("killProcessesBelowAdj() only available to system");
8835        }
8836
8837        boolean killed = false;
8838        synchronized (mPidsSelfLocked) {
8839            final int size = mPidsSelfLocked.size();
8840            for (int i = 0; i < size; i++) {
8841                final int pid = mPidsSelfLocked.keyAt(i);
8842                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8843                if (proc == null) continue;
8844
8845                final int adj = proc.setAdj;
8846                if (adj > belowAdj && !proc.killedByAm) {
8847                    killUnneededProcessLocked(proc, reason);
8848                    killed = true;
8849                }
8850            }
8851        }
8852        return killed;
8853    }
8854
8855    @Override
8856    public void hang(final IBinder who, boolean allowRestart) {
8857        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8858                != PackageManager.PERMISSION_GRANTED) {
8859            throw new SecurityException("Requires permission "
8860                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8861        }
8862
8863        final IBinder.DeathRecipient death = new DeathRecipient() {
8864            @Override
8865            public void binderDied() {
8866                synchronized (this) {
8867                    notifyAll();
8868                }
8869            }
8870        };
8871
8872        try {
8873            who.linkToDeath(death, 0);
8874        } catch (RemoteException e) {
8875            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8876            return;
8877        }
8878
8879        synchronized (this) {
8880            Watchdog.getInstance().setAllowRestart(allowRestart);
8881            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8882            synchronized (death) {
8883                while (who.isBinderAlive()) {
8884                    try {
8885                        death.wait();
8886                    } catch (InterruptedException e) {
8887                    }
8888                }
8889            }
8890            Watchdog.getInstance().setAllowRestart(true);
8891        }
8892    }
8893
8894    @Override
8895    public void restart() {
8896        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8897                != PackageManager.PERMISSION_GRANTED) {
8898            throw new SecurityException("Requires permission "
8899                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8900        }
8901
8902        Log.i(TAG, "Sending shutdown broadcast...");
8903
8904        BroadcastReceiver br = new BroadcastReceiver() {
8905            @Override public void onReceive(Context context, Intent intent) {
8906                // Now the broadcast is done, finish up the low-level shutdown.
8907                Log.i(TAG, "Shutting down activity manager...");
8908                shutdown(10000);
8909                Log.i(TAG, "Shutdown complete, restarting!");
8910                Process.killProcess(Process.myPid());
8911                System.exit(10);
8912            }
8913        };
8914
8915        // First send the high-level shut down broadcast.
8916        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8917        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8918        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8919        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8920        mContext.sendOrderedBroadcastAsUser(intent,
8921                UserHandle.ALL, null, br, mHandler, 0, null, null);
8922        */
8923        br.onReceive(mContext, intent);
8924    }
8925
8926    private long getLowRamTimeSinceIdle(long now) {
8927        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8928    }
8929
8930    @Override
8931    public void performIdleMaintenance() {
8932        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8933                != PackageManager.PERMISSION_GRANTED) {
8934            throw new SecurityException("Requires permission "
8935                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8936        }
8937
8938        synchronized (this) {
8939            final long now = SystemClock.uptimeMillis();
8940            final long timeSinceLastIdle = now - mLastIdleTime;
8941            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8942            mLastIdleTime = now;
8943            mLowRamTimeSinceLastIdle = 0;
8944            if (mLowRamStartTime != 0) {
8945                mLowRamStartTime = now;
8946            }
8947
8948            StringBuilder sb = new StringBuilder(128);
8949            sb.append("Idle maintenance over ");
8950            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8951            sb.append(" low RAM for ");
8952            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8953            Slog.i(TAG, sb.toString());
8954
8955            // If at least 1/3 of our time since the last idle period has been spent
8956            // with RAM low, then we want to kill processes.
8957            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8958
8959            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8960                ProcessRecord proc = mLruProcesses.get(i);
8961                if (proc.notCachedSinceIdle) {
8962                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8963                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8964                        if (doKilling && proc.initialIdlePss != 0
8965                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8966                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8967                                    + " from " + proc.initialIdlePss + ")");
8968                        }
8969                    }
8970                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8971                    proc.notCachedSinceIdle = true;
8972                    proc.initialIdlePss = 0;
8973                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8974                            mSleeping, now);
8975                }
8976            }
8977
8978            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8979            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8980        }
8981    }
8982
8983    public final void startRunning(String pkg, String cls, String action,
8984            String data) {
8985        synchronized(this) {
8986            if (mStartRunning) {
8987                return;
8988            }
8989            mStartRunning = true;
8990            mTopComponent = pkg != null && cls != null
8991                    ? new ComponentName(pkg, cls) : null;
8992            mTopAction = action != null ? action : Intent.ACTION_MAIN;
8993            mTopData = data;
8994            if (!mSystemReady) {
8995                return;
8996            }
8997        }
8998
8999        systemReady(null);
9000    }
9001
9002    private void retrieveSettings() {
9003        final ContentResolver resolver = mContext.getContentResolver();
9004        String debugApp = Settings.Global.getString(
9005            resolver, Settings.Global.DEBUG_APP);
9006        boolean waitForDebugger = Settings.Global.getInt(
9007            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9008        boolean alwaysFinishActivities = Settings.Global.getInt(
9009            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9010        boolean forceRtl = Settings.Global.getInt(
9011                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9012        // Transfer any global setting for forcing RTL layout, into a System Property
9013        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9014
9015        Configuration configuration = new Configuration();
9016        Settings.System.getConfiguration(resolver, configuration);
9017        if (forceRtl) {
9018            // This will take care of setting the correct layout direction flags
9019            configuration.setLayoutDirection(configuration.locale);
9020        }
9021
9022        synchronized (this) {
9023            mDebugApp = mOrigDebugApp = debugApp;
9024            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9025            mAlwaysFinishActivities = alwaysFinishActivities;
9026            // This happens before any activities are started, so we can
9027            // change mConfiguration in-place.
9028            updateConfigurationLocked(configuration, null, false, true);
9029            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9030        }
9031    }
9032
9033    public boolean testIsSystemReady() {
9034        // no need to synchronize(this) just to read & return the value
9035        return mSystemReady;
9036    }
9037
9038    private static File getCalledPreBootReceiversFile() {
9039        File dataDir = Environment.getDataDirectory();
9040        File systemDir = new File(dataDir, "system");
9041        File fname = new File(systemDir, "called_pre_boots.dat");
9042        return fname;
9043    }
9044
9045    static final int LAST_DONE_VERSION = 10000;
9046
9047    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9048        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9049        File file = getCalledPreBootReceiversFile();
9050        FileInputStream fis = null;
9051        try {
9052            fis = new FileInputStream(file);
9053            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9054            int fvers = dis.readInt();
9055            if (fvers == LAST_DONE_VERSION) {
9056                String vers = dis.readUTF();
9057                String codename = dis.readUTF();
9058                String build = dis.readUTF();
9059                if (android.os.Build.VERSION.RELEASE.equals(vers)
9060                        && android.os.Build.VERSION.CODENAME.equals(codename)
9061                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9062                    int num = dis.readInt();
9063                    while (num > 0) {
9064                        num--;
9065                        String pkg = dis.readUTF();
9066                        String cls = dis.readUTF();
9067                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9068                    }
9069                }
9070            }
9071        } catch (FileNotFoundException e) {
9072        } catch (IOException e) {
9073            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9074        } finally {
9075            if (fis != null) {
9076                try {
9077                    fis.close();
9078                } catch (IOException e) {
9079                }
9080            }
9081        }
9082        return lastDoneReceivers;
9083    }
9084
9085    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9086        File file = getCalledPreBootReceiversFile();
9087        FileOutputStream fos = null;
9088        DataOutputStream dos = null;
9089        try {
9090            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9091            fos = new FileOutputStream(file);
9092            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9093            dos.writeInt(LAST_DONE_VERSION);
9094            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9095            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9096            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9097            dos.writeInt(list.size());
9098            for (int i=0; i<list.size(); i++) {
9099                dos.writeUTF(list.get(i).getPackageName());
9100                dos.writeUTF(list.get(i).getClassName());
9101            }
9102        } catch (IOException e) {
9103            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9104            file.delete();
9105        } finally {
9106            FileUtils.sync(fos);
9107            if (dos != null) {
9108                try {
9109                    dos.close();
9110                } catch (IOException e) {
9111                    // TODO Auto-generated catch block
9112                    e.printStackTrace();
9113                }
9114            }
9115        }
9116    }
9117
9118    public void systemReady(final Runnable goingCallback) {
9119        synchronized(this) {
9120            if (mSystemReady) {
9121                if (goingCallback != null) goingCallback.run();
9122                return;
9123            }
9124
9125            // Check to see if there are any update receivers to run.
9126            if (!mDidUpdate) {
9127                if (mWaitingUpdate) {
9128                    return;
9129                }
9130                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9131                List<ResolveInfo> ris = null;
9132                try {
9133                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9134                            intent, null, 0, 0);
9135                } catch (RemoteException e) {
9136                }
9137                if (ris != null) {
9138                    for (int i=ris.size()-1; i>=0; i--) {
9139                        if ((ris.get(i).activityInfo.applicationInfo.flags
9140                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9141                            ris.remove(i);
9142                        }
9143                    }
9144                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9145
9146                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9147
9148                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9149                    for (int i=0; i<ris.size(); i++) {
9150                        ActivityInfo ai = ris.get(i).activityInfo;
9151                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9152                        if (lastDoneReceivers.contains(comp)) {
9153                            ris.remove(i);
9154                            i--;
9155                        }
9156                    }
9157
9158                    final int[] users = getUsersLocked();
9159                    for (int i=0; i<ris.size(); i++) {
9160                        ActivityInfo ai = ris.get(i).activityInfo;
9161                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9162                        doneReceivers.add(comp);
9163                        intent.setComponent(comp);
9164                        for (int j=0; j<users.length; j++) {
9165                            IIntentReceiver finisher = null;
9166                            if (i == ris.size()-1 && j == users.length-1) {
9167                                finisher = new IIntentReceiver.Stub() {
9168                                    public void performReceive(Intent intent, int resultCode,
9169                                            String data, Bundle extras, boolean ordered,
9170                                            boolean sticky, int sendingUser) {
9171                                        // The raw IIntentReceiver interface is called
9172                                        // with the AM lock held, so redispatch to
9173                                        // execute our code without the lock.
9174                                        mHandler.post(new Runnable() {
9175                                            public void run() {
9176                                                synchronized (ActivityManagerService.this) {
9177                                                    mDidUpdate = true;
9178                                                }
9179                                                writeLastDonePreBootReceivers(doneReceivers);
9180                                                showBootMessage(mContext.getText(
9181                                                        R.string.android_upgrading_complete),
9182                                                        false);
9183                                                systemReady(goingCallback);
9184                                            }
9185                                        });
9186                                    }
9187                                };
9188                            }
9189                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9190                                    + " for user " + users[j]);
9191                            broadcastIntentLocked(null, null, intent, null, finisher,
9192                                    0, null, null, null, AppOpsManager.OP_NONE,
9193                                    true, false, MY_PID, Process.SYSTEM_UID,
9194                                    users[j]);
9195                            if (finisher != null) {
9196                                mWaitingUpdate = true;
9197                            }
9198                        }
9199                    }
9200                }
9201                if (mWaitingUpdate) {
9202                    return;
9203                }
9204                mDidUpdate = true;
9205            }
9206
9207            mAppOpsService.systemReady();
9208            mSystemReady = true;
9209            if (!mStartRunning) {
9210                return;
9211            }
9212        }
9213
9214        ArrayList<ProcessRecord> procsToKill = null;
9215        synchronized(mPidsSelfLocked) {
9216            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9217                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9218                if (!isAllowedWhileBooting(proc.info)){
9219                    if (procsToKill == null) {
9220                        procsToKill = new ArrayList<ProcessRecord>();
9221                    }
9222                    procsToKill.add(proc);
9223                }
9224            }
9225        }
9226
9227        synchronized(this) {
9228            if (procsToKill != null) {
9229                for (int i=procsToKill.size()-1; i>=0; i--) {
9230                    ProcessRecord proc = procsToKill.get(i);
9231                    Slog.i(TAG, "Removing system update proc: " + proc);
9232                    removeProcessLocked(proc, true, false, "system update done");
9233                }
9234            }
9235
9236            // Now that we have cleaned up any update processes, we
9237            // are ready to start launching real processes and know that
9238            // we won't trample on them any more.
9239            mProcessesReady = true;
9240        }
9241
9242        Slog.i(TAG, "System now ready");
9243        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9244            SystemClock.uptimeMillis());
9245
9246        synchronized(this) {
9247            // Make sure we have no pre-ready processes sitting around.
9248
9249            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9250                ResolveInfo ri = mContext.getPackageManager()
9251                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9252                                STOCK_PM_FLAGS);
9253                CharSequence errorMsg = null;
9254                if (ri != null) {
9255                    ActivityInfo ai = ri.activityInfo;
9256                    ApplicationInfo app = ai.applicationInfo;
9257                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9258                        mTopAction = Intent.ACTION_FACTORY_TEST;
9259                        mTopData = null;
9260                        mTopComponent = new ComponentName(app.packageName,
9261                                ai.name);
9262                    } else {
9263                        errorMsg = mContext.getResources().getText(
9264                                com.android.internal.R.string.factorytest_not_system);
9265                    }
9266                } else {
9267                    errorMsg = mContext.getResources().getText(
9268                            com.android.internal.R.string.factorytest_no_action);
9269                }
9270                if (errorMsg != null) {
9271                    mTopAction = null;
9272                    mTopData = null;
9273                    mTopComponent = null;
9274                    Message msg = Message.obtain();
9275                    msg.what = SHOW_FACTORY_ERROR_MSG;
9276                    msg.getData().putCharSequence("msg", errorMsg);
9277                    mHandler.sendMessage(msg);
9278                }
9279            }
9280        }
9281
9282        retrieveSettings();
9283
9284        synchronized (this) {
9285            readGrantedUriPermissionsLocked();
9286        }
9287
9288        if (goingCallback != null) goingCallback.run();
9289
9290        synchronized (this) {
9291            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9292                try {
9293                    List apps = AppGlobals.getPackageManager().
9294                        getPersistentApplications(STOCK_PM_FLAGS);
9295                    if (apps != null) {
9296                        int N = apps.size();
9297                        int i;
9298                        for (i=0; i<N; i++) {
9299                            ApplicationInfo info
9300                                = (ApplicationInfo)apps.get(i);
9301                            if (info != null &&
9302                                    !info.packageName.equals("android")) {
9303                                addAppLocked(info, false);
9304                            }
9305                        }
9306                    }
9307                } catch (RemoteException ex) {
9308                    // pm is in same process, this will never happen.
9309                }
9310            }
9311
9312            // Start up initial activity.
9313            mBooting = true;
9314
9315            try {
9316                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9317                    Message msg = Message.obtain();
9318                    msg.what = SHOW_UID_ERROR_MSG;
9319                    mHandler.sendMessage(msg);
9320                }
9321            } catch (RemoteException e) {
9322            }
9323
9324            long ident = Binder.clearCallingIdentity();
9325            try {
9326                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9327                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9328                        | Intent.FLAG_RECEIVER_FOREGROUND);
9329                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9330                broadcastIntentLocked(null, null, intent,
9331                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9332                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9333                intent = new Intent(Intent.ACTION_USER_STARTING);
9334                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9335                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9336                broadcastIntentLocked(null, null, intent,
9337                        null, new IIntentReceiver.Stub() {
9338                            @Override
9339                            public void performReceive(Intent intent, int resultCode, String data,
9340                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9341                                    throws RemoteException {
9342                            }
9343                        }, 0, null, null,
9344                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9345                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9346            } finally {
9347                Binder.restoreCallingIdentity(ident);
9348            }
9349            mStackSupervisor.resumeTopActivitiesLocked();
9350            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9351        }
9352    }
9353
9354    private boolean makeAppCrashingLocked(ProcessRecord app,
9355            String shortMsg, String longMsg, String stackTrace) {
9356        app.crashing = true;
9357        app.crashingReport = generateProcessError(app,
9358                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9359        startAppProblemLocked(app);
9360        app.stopFreezingAllLocked();
9361        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9362    }
9363
9364    private void makeAppNotRespondingLocked(ProcessRecord app,
9365            String activity, String shortMsg, String longMsg) {
9366        app.notResponding = true;
9367        app.notRespondingReport = generateProcessError(app,
9368                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9369                activity, shortMsg, longMsg, null);
9370        startAppProblemLocked(app);
9371        app.stopFreezingAllLocked();
9372    }
9373
9374    /**
9375     * Generate a process error record, suitable for attachment to a ProcessRecord.
9376     *
9377     * @param app The ProcessRecord in which the error occurred.
9378     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9379     *                      ActivityManager.AppErrorStateInfo
9380     * @param activity The activity associated with the crash, if known.
9381     * @param shortMsg Short message describing the crash.
9382     * @param longMsg Long message describing the crash.
9383     * @param stackTrace Full crash stack trace, may be null.
9384     *
9385     * @return Returns a fully-formed AppErrorStateInfo record.
9386     */
9387    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9388            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9389        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9390
9391        report.condition = condition;
9392        report.processName = app.processName;
9393        report.pid = app.pid;
9394        report.uid = app.info.uid;
9395        report.tag = activity;
9396        report.shortMsg = shortMsg;
9397        report.longMsg = longMsg;
9398        report.stackTrace = stackTrace;
9399
9400        return report;
9401    }
9402
9403    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9404        synchronized (this) {
9405            app.crashing = false;
9406            app.crashingReport = null;
9407            app.notResponding = false;
9408            app.notRespondingReport = null;
9409            if (app.anrDialog == fromDialog) {
9410                app.anrDialog = null;
9411            }
9412            if (app.waitDialog == fromDialog) {
9413                app.waitDialog = null;
9414            }
9415            if (app.pid > 0 && app.pid != MY_PID) {
9416                handleAppCrashLocked(app, null, null, null);
9417                killUnneededProcessLocked(app, "user request after error");
9418            }
9419        }
9420    }
9421
9422    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9423            String stackTrace) {
9424        long now = SystemClock.uptimeMillis();
9425
9426        Long crashTime;
9427        if (!app.isolated) {
9428            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9429        } else {
9430            crashTime = null;
9431        }
9432        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9433            // This process loses!
9434            Slog.w(TAG, "Process " + app.info.processName
9435                    + " has crashed too many times: killing!");
9436            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9437                    app.userId, app.info.processName, app.uid);
9438            mStackSupervisor.handleAppCrashLocked(app);
9439            if (!app.persistent) {
9440                // We don't want to start this process again until the user
9441                // explicitly does so...  but for persistent process, we really
9442                // need to keep it running.  If a persistent process is actually
9443                // repeatedly crashing, then badness for everyone.
9444                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9445                        app.info.processName);
9446                if (!app.isolated) {
9447                    // XXX We don't have a way to mark isolated processes
9448                    // as bad, since they don't have a peristent identity.
9449                    mBadProcesses.put(app.info.processName, app.uid,
9450                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9451                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9452                }
9453                app.bad = true;
9454                app.removed = true;
9455                // Don't let services in this process be restarted and potentially
9456                // annoy the user repeatedly.  Unless it is persistent, since those
9457                // processes run critical code.
9458                removeProcessLocked(app, false, false, "crash");
9459                mStackSupervisor.resumeTopActivitiesLocked();
9460                return false;
9461            }
9462            mStackSupervisor.resumeTopActivitiesLocked();
9463        } else {
9464            mStackSupervisor.finishTopRunningActivityLocked(app);
9465        }
9466
9467        // Bump up the crash count of any services currently running in the proc.
9468        for (int i=app.services.size()-1; i>=0; i--) {
9469            // Any services running in the application need to be placed
9470            // back in the pending list.
9471            ServiceRecord sr = app.services.valueAt(i);
9472            sr.crashCount++;
9473        }
9474
9475        // If the crashing process is what we consider to be the "home process" and it has been
9476        // replaced by a third-party app, clear the package preferred activities from packages
9477        // with a home activity running in the process to prevent a repeatedly crashing app
9478        // from blocking the user to manually clear the list.
9479        final ArrayList<ActivityRecord> activities = app.activities;
9480        if (app == mHomeProcess && activities.size() > 0
9481                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9482            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9483                final ActivityRecord r = activities.get(activityNdx);
9484                if (r.isHomeActivity()) {
9485                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9486                    try {
9487                        ActivityThread.getPackageManager()
9488                                .clearPackagePreferredActivities(r.packageName);
9489                    } catch (RemoteException c) {
9490                        // pm is in same process, this will never happen.
9491                    }
9492                }
9493            }
9494        }
9495
9496        if (!app.isolated) {
9497            // XXX Can't keep track of crash times for isolated processes,
9498            // because they don't have a perisistent identity.
9499            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9500        }
9501
9502        return true;
9503    }
9504
9505    void startAppProblemLocked(ProcessRecord app) {
9506        if (app.userId == mCurrentUserId) {
9507            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9508                    mContext, app.info.packageName, app.info.flags);
9509        } else {
9510            // If this app is not running under the current user, then we
9511            // can't give it a report button because that would require
9512            // launching the report UI under a different user.
9513            app.errorReportReceiver = null;
9514        }
9515        skipCurrentReceiverLocked(app);
9516    }
9517
9518    void skipCurrentReceiverLocked(ProcessRecord app) {
9519        for (BroadcastQueue queue : mBroadcastQueues) {
9520            queue.skipCurrentReceiverLocked(app);
9521        }
9522    }
9523
9524    /**
9525     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9526     * The application process will exit immediately after this call returns.
9527     * @param app object of the crashing app, null for the system server
9528     * @param crashInfo describing the exception
9529     */
9530    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9531        ProcessRecord r = findAppProcess(app, "Crash");
9532        final String processName = app == null ? "system_server"
9533                : (r == null ? "unknown" : r.processName);
9534
9535        handleApplicationCrashInner("crash", r, processName, crashInfo);
9536    }
9537
9538    /* Native crash reporting uses this inner version because it needs to be somewhat
9539     * decoupled from the AM-managed cleanup lifecycle
9540     */
9541    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9542            ApplicationErrorReport.CrashInfo crashInfo) {
9543        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9544                UserHandle.getUserId(Binder.getCallingUid()), processName,
9545                r == null ? -1 : r.info.flags,
9546                crashInfo.exceptionClassName,
9547                crashInfo.exceptionMessage,
9548                crashInfo.throwFileName,
9549                crashInfo.throwLineNumber);
9550
9551        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9552
9553        crashApplication(r, crashInfo);
9554    }
9555
9556    public void handleApplicationStrictModeViolation(
9557            IBinder app,
9558            int violationMask,
9559            StrictMode.ViolationInfo info) {
9560        ProcessRecord r = findAppProcess(app, "StrictMode");
9561        if (r == null) {
9562            return;
9563        }
9564
9565        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9566            Integer stackFingerprint = info.hashCode();
9567            boolean logIt = true;
9568            synchronized (mAlreadyLoggedViolatedStacks) {
9569                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9570                    logIt = false;
9571                    // TODO: sub-sample into EventLog for these, with
9572                    // the info.durationMillis?  Then we'd get
9573                    // the relative pain numbers, without logging all
9574                    // the stack traces repeatedly.  We'd want to do
9575                    // likewise in the client code, which also does
9576                    // dup suppression, before the Binder call.
9577                } else {
9578                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9579                        mAlreadyLoggedViolatedStacks.clear();
9580                    }
9581                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9582                }
9583            }
9584            if (logIt) {
9585                logStrictModeViolationToDropBox(r, info);
9586            }
9587        }
9588
9589        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9590            AppErrorResult result = new AppErrorResult();
9591            synchronized (this) {
9592                final long origId = Binder.clearCallingIdentity();
9593
9594                Message msg = Message.obtain();
9595                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9596                HashMap<String, Object> data = new HashMap<String, Object>();
9597                data.put("result", result);
9598                data.put("app", r);
9599                data.put("violationMask", violationMask);
9600                data.put("info", info);
9601                msg.obj = data;
9602                mHandler.sendMessage(msg);
9603
9604                Binder.restoreCallingIdentity(origId);
9605            }
9606            int res = result.get();
9607            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9608        }
9609    }
9610
9611    // Depending on the policy in effect, there could be a bunch of
9612    // these in quick succession so we try to batch these together to
9613    // minimize disk writes, number of dropbox entries, and maximize
9614    // compression, by having more fewer, larger records.
9615    private void logStrictModeViolationToDropBox(
9616            ProcessRecord process,
9617            StrictMode.ViolationInfo info) {
9618        if (info == null) {
9619            return;
9620        }
9621        final boolean isSystemApp = process == null ||
9622                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9623                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9624        final String processName = process == null ? "unknown" : process.processName;
9625        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9626        final DropBoxManager dbox = (DropBoxManager)
9627                mContext.getSystemService(Context.DROPBOX_SERVICE);
9628
9629        // Exit early if the dropbox isn't configured to accept this report type.
9630        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9631
9632        boolean bufferWasEmpty;
9633        boolean needsFlush;
9634        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9635        synchronized (sb) {
9636            bufferWasEmpty = sb.length() == 0;
9637            appendDropBoxProcessHeaders(process, processName, sb);
9638            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9639            sb.append("System-App: ").append(isSystemApp).append("\n");
9640            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9641            if (info.violationNumThisLoop != 0) {
9642                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9643            }
9644            if (info.numAnimationsRunning != 0) {
9645                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9646            }
9647            if (info.broadcastIntentAction != null) {
9648                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9649            }
9650            if (info.durationMillis != -1) {
9651                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9652            }
9653            if (info.numInstances != -1) {
9654                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9655            }
9656            if (info.tags != null) {
9657                for (String tag : info.tags) {
9658                    sb.append("Span-Tag: ").append(tag).append("\n");
9659                }
9660            }
9661            sb.append("\n");
9662            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9663                sb.append(info.crashInfo.stackTrace);
9664            }
9665            sb.append("\n");
9666
9667            // Only buffer up to ~64k.  Various logging bits truncate
9668            // things at 128k.
9669            needsFlush = (sb.length() > 64 * 1024);
9670        }
9671
9672        // Flush immediately if the buffer's grown too large, or this
9673        // is a non-system app.  Non-system apps are isolated with a
9674        // different tag & policy and not batched.
9675        //
9676        // Batching is useful during internal testing with
9677        // StrictMode settings turned up high.  Without batching,
9678        // thousands of separate files could be created on boot.
9679        if (!isSystemApp || needsFlush) {
9680            new Thread("Error dump: " + dropboxTag) {
9681                @Override
9682                public void run() {
9683                    String report;
9684                    synchronized (sb) {
9685                        report = sb.toString();
9686                        sb.delete(0, sb.length());
9687                        sb.trimToSize();
9688                    }
9689                    if (report.length() != 0) {
9690                        dbox.addText(dropboxTag, report);
9691                    }
9692                }
9693            }.start();
9694            return;
9695        }
9696
9697        // System app batching:
9698        if (!bufferWasEmpty) {
9699            // An existing dropbox-writing thread is outstanding, so
9700            // we don't need to start it up.  The existing thread will
9701            // catch the buffer appends we just did.
9702            return;
9703        }
9704
9705        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9706        // (After this point, we shouldn't access AMS internal data structures.)
9707        new Thread("Error dump: " + dropboxTag) {
9708            @Override
9709            public void run() {
9710                // 5 second sleep to let stacks arrive and be batched together
9711                try {
9712                    Thread.sleep(5000);  // 5 seconds
9713                } catch (InterruptedException e) {}
9714
9715                String errorReport;
9716                synchronized (mStrictModeBuffer) {
9717                    errorReport = mStrictModeBuffer.toString();
9718                    if (errorReport.length() == 0) {
9719                        return;
9720                    }
9721                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9722                    mStrictModeBuffer.trimToSize();
9723                }
9724                dbox.addText(dropboxTag, errorReport);
9725            }
9726        }.start();
9727    }
9728
9729    /**
9730     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9731     * @param app object of the crashing app, null for the system server
9732     * @param tag reported by the caller
9733     * @param crashInfo describing the context of the error
9734     * @return true if the process should exit immediately (WTF is fatal)
9735     */
9736    public boolean handleApplicationWtf(IBinder app, String tag,
9737            ApplicationErrorReport.CrashInfo crashInfo) {
9738        ProcessRecord r = findAppProcess(app, "WTF");
9739        final String processName = app == null ? "system_server"
9740                : (r == null ? "unknown" : r.processName);
9741
9742        EventLog.writeEvent(EventLogTags.AM_WTF,
9743                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9744                processName,
9745                r == null ? -1 : r.info.flags,
9746                tag, crashInfo.exceptionMessage);
9747
9748        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9749
9750        if (r != null && r.pid != Process.myPid() &&
9751                Settings.Global.getInt(mContext.getContentResolver(),
9752                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9753            crashApplication(r, crashInfo);
9754            return true;
9755        } else {
9756            return false;
9757        }
9758    }
9759
9760    /**
9761     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9762     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9763     */
9764    private ProcessRecord findAppProcess(IBinder app, String reason) {
9765        if (app == null) {
9766            return null;
9767        }
9768
9769        synchronized (this) {
9770            final int NP = mProcessNames.getMap().size();
9771            for (int ip=0; ip<NP; ip++) {
9772                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9773                final int NA = apps.size();
9774                for (int ia=0; ia<NA; ia++) {
9775                    ProcessRecord p = apps.valueAt(ia);
9776                    if (p.thread != null && p.thread.asBinder() == app) {
9777                        return p;
9778                    }
9779                }
9780            }
9781
9782            Slog.w(TAG, "Can't find mystery application for " + reason
9783                    + " from pid=" + Binder.getCallingPid()
9784                    + " uid=" + Binder.getCallingUid() + ": " + app);
9785            return null;
9786        }
9787    }
9788
9789    /**
9790     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9791     * to append various headers to the dropbox log text.
9792     */
9793    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9794            StringBuilder sb) {
9795        // Watchdog thread ends up invoking this function (with
9796        // a null ProcessRecord) to add the stack file to dropbox.
9797        // Do not acquire a lock on this (am) in such cases, as it
9798        // could cause a potential deadlock, if and when watchdog
9799        // is invoked due to unavailability of lock on am and it
9800        // would prevent watchdog from killing system_server.
9801        if (process == null) {
9802            sb.append("Process: ").append(processName).append("\n");
9803            return;
9804        }
9805        // Note: ProcessRecord 'process' is guarded by the service
9806        // instance.  (notably process.pkgList, which could otherwise change
9807        // concurrently during execution of this method)
9808        synchronized (this) {
9809            sb.append("Process: ").append(processName).append("\n");
9810            int flags = process.info.flags;
9811            IPackageManager pm = AppGlobals.getPackageManager();
9812            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9813            for (int ip=0; ip<process.pkgList.size(); ip++) {
9814                String pkg = process.pkgList.keyAt(ip);
9815                sb.append("Package: ").append(pkg);
9816                try {
9817                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9818                    if (pi != null) {
9819                        sb.append(" v").append(pi.versionCode);
9820                        if (pi.versionName != null) {
9821                            sb.append(" (").append(pi.versionName).append(")");
9822                        }
9823                    }
9824                } catch (RemoteException e) {
9825                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9826                }
9827                sb.append("\n");
9828            }
9829        }
9830    }
9831
9832    private static String processClass(ProcessRecord process) {
9833        if (process == null || process.pid == MY_PID) {
9834            return "system_server";
9835        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9836            return "system_app";
9837        } else {
9838            return "data_app";
9839        }
9840    }
9841
9842    /**
9843     * Write a description of an error (crash, WTF, ANR) to the drop box.
9844     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9845     * @param process which caused the error, null means the system server
9846     * @param activity which triggered the error, null if unknown
9847     * @param parent activity related to the error, null if unknown
9848     * @param subject line related to the error, null if absent
9849     * @param report in long form describing the error, null if absent
9850     * @param logFile to include in the report, null if none
9851     * @param crashInfo giving an application stack trace, null if absent
9852     */
9853    public void addErrorToDropBox(String eventType,
9854            ProcessRecord process, String processName, ActivityRecord activity,
9855            ActivityRecord parent, String subject,
9856            final String report, final File logFile,
9857            final ApplicationErrorReport.CrashInfo crashInfo) {
9858        // NOTE -- this must never acquire the ActivityManagerService lock,
9859        // otherwise the watchdog may be prevented from resetting the system.
9860
9861        final String dropboxTag = processClass(process) + "_" + eventType;
9862        final DropBoxManager dbox = (DropBoxManager)
9863                mContext.getSystemService(Context.DROPBOX_SERVICE);
9864
9865        // Exit early if the dropbox isn't configured to accept this report type.
9866        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9867
9868        final StringBuilder sb = new StringBuilder(1024);
9869        appendDropBoxProcessHeaders(process, processName, sb);
9870        if (activity != null) {
9871            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9872        }
9873        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9874            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9875        }
9876        if (parent != null && parent != activity) {
9877            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9878        }
9879        if (subject != null) {
9880            sb.append("Subject: ").append(subject).append("\n");
9881        }
9882        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9883        if (Debug.isDebuggerConnected()) {
9884            sb.append("Debugger: Connected\n");
9885        }
9886        sb.append("\n");
9887
9888        // Do the rest in a worker thread to avoid blocking the caller on I/O
9889        // (After this point, we shouldn't access AMS internal data structures.)
9890        Thread worker = new Thread("Error dump: " + dropboxTag) {
9891            @Override
9892            public void run() {
9893                if (report != null) {
9894                    sb.append(report);
9895                }
9896                if (logFile != null) {
9897                    try {
9898                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9899                                    "\n\n[[TRUNCATED]]"));
9900                    } catch (IOException e) {
9901                        Slog.e(TAG, "Error reading " + logFile, e);
9902                    }
9903                }
9904                if (crashInfo != null && crashInfo.stackTrace != null) {
9905                    sb.append(crashInfo.stackTrace);
9906                }
9907
9908                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9909                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9910                if (lines > 0) {
9911                    sb.append("\n");
9912
9913                    // Merge several logcat streams, and take the last N lines
9914                    InputStreamReader input = null;
9915                    try {
9916                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9917                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9918                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9919
9920                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9921                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9922                        input = new InputStreamReader(logcat.getInputStream());
9923
9924                        int num;
9925                        char[] buf = new char[8192];
9926                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9927                    } catch (IOException e) {
9928                        Slog.e(TAG, "Error running logcat", e);
9929                    } finally {
9930                        if (input != null) try { input.close(); } catch (IOException e) {}
9931                    }
9932                }
9933
9934                dbox.addText(dropboxTag, sb.toString());
9935            }
9936        };
9937
9938        if (process == null) {
9939            // If process is null, we are being called from some internal code
9940            // and may be about to die -- run this synchronously.
9941            worker.run();
9942        } else {
9943            worker.start();
9944        }
9945    }
9946
9947    /**
9948     * Bring up the "unexpected error" dialog box for a crashing app.
9949     * Deal with edge cases (intercepts from instrumented applications,
9950     * ActivityController, error intent receivers, that sort of thing).
9951     * @param r the application crashing
9952     * @param crashInfo describing the failure
9953     */
9954    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9955        long timeMillis = System.currentTimeMillis();
9956        String shortMsg = crashInfo.exceptionClassName;
9957        String longMsg = crashInfo.exceptionMessage;
9958        String stackTrace = crashInfo.stackTrace;
9959        if (shortMsg != null && longMsg != null) {
9960            longMsg = shortMsg + ": " + longMsg;
9961        } else if (shortMsg != null) {
9962            longMsg = shortMsg;
9963        }
9964
9965        AppErrorResult result = new AppErrorResult();
9966        synchronized (this) {
9967            if (mController != null) {
9968                try {
9969                    String name = r != null ? r.processName : null;
9970                    int pid = r != null ? r.pid : Binder.getCallingPid();
9971                    if (!mController.appCrashed(name, pid,
9972                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9973                        Slog.w(TAG, "Force-killing crashed app " + name
9974                                + " at watcher's request");
9975                        Process.killProcess(pid);
9976                        return;
9977                    }
9978                } catch (RemoteException e) {
9979                    mController = null;
9980                    Watchdog.getInstance().setActivityController(null);
9981                }
9982            }
9983
9984            final long origId = Binder.clearCallingIdentity();
9985
9986            // If this process is running instrumentation, finish it.
9987            if (r != null && r.instrumentationClass != null) {
9988                Slog.w(TAG, "Error in app " + r.processName
9989                      + " running instrumentation " + r.instrumentationClass + ":");
9990                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9991                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9992                Bundle info = new Bundle();
9993                info.putString("shortMsg", shortMsg);
9994                info.putString("longMsg", longMsg);
9995                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9996                Binder.restoreCallingIdentity(origId);
9997                return;
9998            }
9999
10000            // If we can't identify the process or it's already exceeded its crash quota,
10001            // quit right away without showing a crash dialog.
10002            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10003                Binder.restoreCallingIdentity(origId);
10004                return;
10005            }
10006
10007            Message msg = Message.obtain();
10008            msg.what = SHOW_ERROR_MSG;
10009            HashMap data = new HashMap();
10010            data.put("result", result);
10011            data.put("app", r);
10012            msg.obj = data;
10013            mHandler.sendMessage(msg);
10014
10015            Binder.restoreCallingIdentity(origId);
10016        }
10017
10018        int res = result.get();
10019
10020        Intent appErrorIntent = null;
10021        synchronized (this) {
10022            if (r != null && !r.isolated) {
10023                // XXX Can't keep track of crash time for isolated processes,
10024                // since they don't have a persistent identity.
10025                mProcessCrashTimes.put(r.info.processName, r.uid,
10026                        SystemClock.uptimeMillis());
10027            }
10028            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10029                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10030            }
10031        }
10032
10033        if (appErrorIntent != null) {
10034            try {
10035                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10036            } catch (ActivityNotFoundException e) {
10037                Slog.w(TAG, "bug report receiver dissappeared", e);
10038            }
10039        }
10040    }
10041
10042    Intent createAppErrorIntentLocked(ProcessRecord r,
10043            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10044        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10045        if (report == null) {
10046            return null;
10047        }
10048        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10049        result.setComponent(r.errorReportReceiver);
10050        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10051        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10052        return result;
10053    }
10054
10055    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10056            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10057        if (r.errorReportReceiver == null) {
10058            return null;
10059        }
10060
10061        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10062            return null;
10063        }
10064
10065        ApplicationErrorReport report = new ApplicationErrorReport();
10066        report.packageName = r.info.packageName;
10067        report.installerPackageName = r.errorReportReceiver.getPackageName();
10068        report.processName = r.processName;
10069        report.time = timeMillis;
10070        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10071
10072        if (r.crashing || r.forceCrashReport) {
10073            report.type = ApplicationErrorReport.TYPE_CRASH;
10074            report.crashInfo = crashInfo;
10075        } else if (r.notResponding) {
10076            report.type = ApplicationErrorReport.TYPE_ANR;
10077            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10078
10079            report.anrInfo.activity = r.notRespondingReport.tag;
10080            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10081            report.anrInfo.info = r.notRespondingReport.longMsg;
10082        }
10083
10084        return report;
10085    }
10086
10087    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10088        enforceNotIsolatedCaller("getProcessesInErrorState");
10089        // assume our apps are happy - lazy create the list
10090        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10091
10092        final boolean allUsers = ActivityManager.checkUidPermission(
10093                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10094                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10095        int userId = UserHandle.getUserId(Binder.getCallingUid());
10096
10097        synchronized (this) {
10098
10099            // iterate across all processes
10100            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10101                ProcessRecord app = mLruProcesses.get(i);
10102                if (!allUsers && app.userId != userId) {
10103                    continue;
10104                }
10105                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10106                    // This one's in trouble, so we'll generate a report for it
10107                    // crashes are higher priority (in case there's a crash *and* an anr)
10108                    ActivityManager.ProcessErrorStateInfo report = null;
10109                    if (app.crashing) {
10110                        report = app.crashingReport;
10111                    } else if (app.notResponding) {
10112                        report = app.notRespondingReport;
10113                    }
10114
10115                    if (report != null) {
10116                        if (errList == null) {
10117                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10118                        }
10119                        errList.add(report);
10120                    } else {
10121                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10122                                " crashing = " + app.crashing +
10123                                " notResponding = " + app.notResponding);
10124                    }
10125                }
10126            }
10127        }
10128
10129        return errList;
10130    }
10131
10132    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10133        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10134            if (currApp != null) {
10135                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10136            }
10137            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10138        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10139            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10140        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10141            if (currApp != null) {
10142                currApp.lru = 0;
10143            }
10144            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10145        } else if (adj >= ProcessList.SERVICE_ADJ) {
10146            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10147        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10148            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10149        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10150            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10151        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10152            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10153        } else {
10154            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10155        }
10156    }
10157
10158    private void fillInProcMemInfo(ProcessRecord app,
10159            ActivityManager.RunningAppProcessInfo outInfo) {
10160        outInfo.pid = app.pid;
10161        outInfo.uid = app.info.uid;
10162        if (mHeavyWeightProcess == app) {
10163            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10164        }
10165        if (app.persistent) {
10166            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10167        }
10168        if (app.activities.size() > 0) {
10169            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10170        }
10171        outInfo.lastTrimLevel = app.trimMemoryLevel;
10172        int adj = app.curAdj;
10173        outInfo.importance = oomAdjToImportance(adj, outInfo);
10174        outInfo.importanceReasonCode = app.adjTypeCode;
10175    }
10176
10177    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10178        enforceNotIsolatedCaller("getRunningAppProcesses");
10179        // Lazy instantiation of list
10180        List<ActivityManager.RunningAppProcessInfo> runList = null;
10181        final boolean allUsers = ActivityManager.checkUidPermission(
10182                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10183                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10184        int userId = UserHandle.getUserId(Binder.getCallingUid());
10185        synchronized (this) {
10186            // Iterate across all processes
10187            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10188                ProcessRecord app = mLruProcesses.get(i);
10189                if (!allUsers && app.userId != userId) {
10190                    continue;
10191                }
10192                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10193                    // Generate process state info for running application
10194                    ActivityManager.RunningAppProcessInfo currApp =
10195                        new ActivityManager.RunningAppProcessInfo(app.processName,
10196                                app.pid, app.getPackageList());
10197                    fillInProcMemInfo(app, currApp);
10198                    if (app.adjSource instanceof ProcessRecord) {
10199                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10200                        currApp.importanceReasonImportance = oomAdjToImportance(
10201                                app.adjSourceOom, null);
10202                    } else if (app.adjSource instanceof ActivityRecord) {
10203                        ActivityRecord r = (ActivityRecord)app.adjSource;
10204                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10205                    }
10206                    if (app.adjTarget instanceof ComponentName) {
10207                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10208                    }
10209                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10210                    //        + " lru=" + currApp.lru);
10211                    if (runList == null) {
10212                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10213                    }
10214                    runList.add(currApp);
10215                }
10216            }
10217        }
10218        return runList;
10219    }
10220
10221    public List<ApplicationInfo> getRunningExternalApplications() {
10222        enforceNotIsolatedCaller("getRunningExternalApplications");
10223        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10224        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10225        if (runningApps != null && runningApps.size() > 0) {
10226            Set<String> extList = new HashSet<String>();
10227            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10228                if (app.pkgList != null) {
10229                    for (String pkg : app.pkgList) {
10230                        extList.add(pkg);
10231                    }
10232                }
10233            }
10234            IPackageManager pm = AppGlobals.getPackageManager();
10235            for (String pkg : extList) {
10236                try {
10237                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10238                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10239                        retList.add(info);
10240                    }
10241                } catch (RemoteException e) {
10242                }
10243            }
10244        }
10245        return retList;
10246    }
10247
10248    @Override
10249    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10250        enforceNotIsolatedCaller("getMyMemoryState");
10251        synchronized (this) {
10252            ProcessRecord proc;
10253            synchronized (mPidsSelfLocked) {
10254                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10255            }
10256            fillInProcMemInfo(proc, outInfo);
10257        }
10258    }
10259
10260    @Override
10261    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10262        if (checkCallingPermission(android.Manifest.permission.DUMP)
10263                != PackageManager.PERMISSION_GRANTED) {
10264            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10265                    + Binder.getCallingPid()
10266                    + ", uid=" + Binder.getCallingUid()
10267                    + " without permission "
10268                    + android.Manifest.permission.DUMP);
10269            return;
10270        }
10271
10272        boolean dumpAll = false;
10273        boolean dumpClient = false;
10274        String dumpPackage = null;
10275
10276        int opti = 0;
10277        while (opti < args.length) {
10278            String opt = args[opti];
10279            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10280                break;
10281            }
10282            opti++;
10283            if ("-a".equals(opt)) {
10284                dumpAll = true;
10285            } else if ("-c".equals(opt)) {
10286                dumpClient = true;
10287            } else if ("-h".equals(opt)) {
10288                pw.println("Activity manager dump options:");
10289                pw.println("  [-a] [-c] [-h] [cmd] ...");
10290                pw.println("  cmd may be one of:");
10291                pw.println("    a[ctivities]: activity stack state");
10292                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10293                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10294                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10295                pw.println("    o[om]: out of memory management");
10296                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10297                pw.println("    provider [COMP_SPEC]: provider client-side state");
10298                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10299                pw.println("    service [COMP_SPEC]: service client-side state");
10300                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10301                pw.println("    all: dump all activities");
10302                pw.println("    top: dump the top activity");
10303                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10304                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10305                pw.println("    a partial substring in a component name, a");
10306                pw.println("    hex object identifier.");
10307                pw.println("  -a: include all available server state.");
10308                pw.println("  -c: include client state.");
10309                return;
10310            } else {
10311                pw.println("Unknown argument: " + opt + "; use -h for help");
10312            }
10313        }
10314
10315        long origId = Binder.clearCallingIdentity();
10316        boolean more = false;
10317        // Is the caller requesting to dump a particular piece of data?
10318        if (opti < args.length) {
10319            String cmd = args[opti];
10320            opti++;
10321            if ("activities".equals(cmd) || "a".equals(cmd)) {
10322                synchronized (this) {
10323                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10324                }
10325            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10326                String[] newArgs;
10327                String name;
10328                if (opti >= args.length) {
10329                    name = null;
10330                    newArgs = EMPTY_STRING_ARRAY;
10331                } else {
10332                    name = args[opti];
10333                    opti++;
10334                    newArgs = new String[args.length - opti];
10335                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10336                            args.length - opti);
10337                }
10338                synchronized (this) {
10339                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10340                }
10341            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10342                String[] newArgs;
10343                String name;
10344                if (opti >= args.length) {
10345                    name = null;
10346                    newArgs = EMPTY_STRING_ARRAY;
10347                } else {
10348                    name = args[opti];
10349                    opti++;
10350                    newArgs = new String[args.length - opti];
10351                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10352                            args.length - opti);
10353                }
10354                synchronized (this) {
10355                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10356                }
10357            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10358                String[] newArgs;
10359                String name;
10360                if (opti >= args.length) {
10361                    name = null;
10362                    newArgs = EMPTY_STRING_ARRAY;
10363                } else {
10364                    name = args[opti];
10365                    opti++;
10366                    newArgs = new String[args.length - opti];
10367                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10368                            args.length - opti);
10369                }
10370                synchronized (this) {
10371                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10372                }
10373            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10374                synchronized (this) {
10375                    dumpOomLocked(fd, pw, args, opti, true);
10376                }
10377            } else if ("provider".equals(cmd)) {
10378                String[] newArgs;
10379                String name;
10380                if (opti >= args.length) {
10381                    name = null;
10382                    newArgs = EMPTY_STRING_ARRAY;
10383                } else {
10384                    name = args[opti];
10385                    opti++;
10386                    newArgs = new String[args.length - opti];
10387                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10388                }
10389                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10390                    pw.println("No providers match: " + name);
10391                    pw.println("Use -h for help.");
10392                }
10393            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10394                synchronized (this) {
10395                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10396                }
10397            } else if ("service".equals(cmd)) {
10398                String[] newArgs;
10399                String name;
10400                if (opti >= args.length) {
10401                    name = null;
10402                    newArgs = EMPTY_STRING_ARRAY;
10403                } else {
10404                    name = args[opti];
10405                    opti++;
10406                    newArgs = new String[args.length - opti];
10407                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10408                            args.length - opti);
10409                }
10410                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10411                    pw.println("No services match: " + name);
10412                    pw.println("Use -h for help.");
10413                }
10414            } else if ("package".equals(cmd)) {
10415                String[] newArgs;
10416                if (opti >= args.length) {
10417                    pw.println("package: no package name specified");
10418                    pw.println("Use -h for help.");
10419                } else {
10420                    dumpPackage = args[opti];
10421                    opti++;
10422                    newArgs = new String[args.length - opti];
10423                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10424                            args.length - opti);
10425                    args = newArgs;
10426                    opti = 0;
10427                    more = true;
10428                }
10429            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10430                synchronized (this) {
10431                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10432                }
10433            } else {
10434                // Dumping a single activity?
10435                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10436                    pw.println("Bad activity command, or no activities match: " + cmd);
10437                    pw.println("Use -h for help.");
10438                }
10439            }
10440            if (!more) {
10441                Binder.restoreCallingIdentity(origId);
10442                return;
10443            }
10444        }
10445
10446        // No piece of data specified, dump everything.
10447        synchronized (this) {
10448            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10449            pw.println();
10450            if (dumpAll) {
10451                pw.println("-------------------------------------------------------------------------------");
10452            }
10453            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10454            pw.println();
10455            if (dumpAll) {
10456                pw.println("-------------------------------------------------------------------------------");
10457            }
10458            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10459            pw.println();
10460            if (dumpAll) {
10461                pw.println("-------------------------------------------------------------------------------");
10462            }
10463            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10464            pw.println();
10465            if (dumpAll) {
10466                pw.println("-------------------------------------------------------------------------------");
10467            }
10468            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10469            pw.println();
10470            if (dumpAll) {
10471                pw.println("-------------------------------------------------------------------------------");
10472            }
10473            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10474        }
10475        Binder.restoreCallingIdentity(origId);
10476    }
10477
10478    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10479            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10480        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10481
10482        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10483                dumpPackage);
10484        boolean needSep = printedAnything;
10485
10486        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10487                dumpPackage, needSep, "  mFocusedActivity: ");
10488        if (printed) {
10489            printedAnything = true;
10490            needSep = false;
10491        }
10492
10493        if (dumpPackage == null) {
10494            if (needSep) {
10495                pw.println();
10496            }
10497            needSep = true;
10498            printedAnything = true;
10499            mStackSupervisor.dump(pw, "  ");
10500        }
10501
10502        if (mRecentTasks.size() > 0) {
10503            boolean printedHeader = false;
10504
10505            final int N = mRecentTasks.size();
10506            for (int i=0; i<N; i++) {
10507                TaskRecord tr = mRecentTasks.get(i);
10508                if (dumpPackage != null) {
10509                    if (tr.realActivity == null ||
10510                            !dumpPackage.equals(tr.realActivity)) {
10511                        continue;
10512                    }
10513                }
10514                if (!printedHeader) {
10515                    if (needSep) {
10516                        pw.println();
10517                    }
10518                    pw.println("  Recent tasks:");
10519                    printedHeader = true;
10520                    printedAnything = true;
10521                }
10522                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10523                        pw.println(tr);
10524                if (dumpAll) {
10525                    mRecentTasks.get(i).dump(pw, "    ");
10526                }
10527            }
10528        }
10529
10530        if (!printedAnything) {
10531            pw.println("  (nothing)");
10532        }
10533    }
10534
10535    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10536            int opti, boolean dumpAll, String dumpPackage) {
10537        boolean needSep = false;
10538        boolean printedAnything = false;
10539        int numPers = 0;
10540
10541        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10542
10543        if (dumpAll) {
10544            final int NP = mProcessNames.getMap().size();
10545            for (int ip=0; ip<NP; ip++) {
10546                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10547                final int NA = procs.size();
10548                for (int ia=0; ia<NA; ia++) {
10549                    ProcessRecord r = procs.valueAt(ia);
10550                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10551                        continue;
10552                    }
10553                    if (!needSep) {
10554                        pw.println("  All known processes:");
10555                        needSep = true;
10556                        printedAnything = true;
10557                    }
10558                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10559                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10560                        pw.print(" "); pw.println(r);
10561                    r.dump(pw, "    ");
10562                    if (r.persistent) {
10563                        numPers++;
10564                    }
10565                }
10566            }
10567        }
10568
10569        if (mIsolatedProcesses.size() > 0) {
10570            boolean printed = false;
10571            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10572                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10573                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10574                    continue;
10575                }
10576                if (!printed) {
10577                    if (needSep) {
10578                        pw.println();
10579                    }
10580                    pw.println("  Isolated process list (sorted by uid):");
10581                    printedAnything = true;
10582                    printed = true;
10583                    needSep = true;
10584                }
10585                pw.println(String.format("%sIsolated #%2d: %s",
10586                        "    ", i, r.toString()));
10587            }
10588        }
10589
10590        if (mLruProcesses.size() > 0) {
10591            if (needSep) {
10592                pw.println();
10593            }
10594            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10595                    pw.print(" total, non-act at ");
10596                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10597                    pw.print(", non-svc at ");
10598                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10599                    pw.println("):");
10600            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10601            needSep = true;
10602            printedAnything = true;
10603        }
10604
10605        if (dumpAll || dumpPackage != null) {
10606            synchronized (mPidsSelfLocked) {
10607                boolean printed = false;
10608                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10609                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10610                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10611                        continue;
10612                    }
10613                    if (!printed) {
10614                        if (needSep) pw.println();
10615                        needSep = true;
10616                        pw.println("  PID mappings:");
10617                        printed = true;
10618                        printedAnything = true;
10619                    }
10620                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10621                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10622                }
10623            }
10624        }
10625
10626        if (mForegroundProcesses.size() > 0) {
10627            synchronized (mPidsSelfLocked) {
10628                boolean printed = false;
10629                for (int i=0; i<mForegroundProcesses.size(); i++) {
10630                    ProcessRecord r = mPidsSelfLocked.get(
10631                            mForegroundProcesses.valueAt(i).pid);
10632                    if (dumpPackage != null && (r == null
10633                            || !r.pkgList.containsKey(dumpPackage))) {
10634                        continue;
10635                    }
10636                    if (!printed) {
10637                        if (needSep) pw.println();
10638                        needSep = true;
10639                        pw.println("  Foreground Processes:");
10640                        printed = true;
10641                        printedAnything = true;
10642                    }
10643                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10644                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10645                }
10646            }
10647        }
10648
10649        if (mPersistentStartingProcesses.size() > 0) {
10650            if (needSep) pw.println();
10651            needSep = true;
10652            printedAnything = true;
10653            pw.println("  Persisent processes that are starting:");
10654            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10655                    "Starting Norm", "Restarting PERS", dumpPackage);
10656        }
10657
10658        if (mRemovedProcesses.size() > 0) {
10659            if (needSep) pw.println();
10660            needSep = true;
10661            printedAnything = true;
10662            pw.println("  Processes that are being removed:");
10663            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10664                    "Removed Norm", "Removed PERS", dumpPackage);
10665        }
10666
10667        if (mProcessesOnHold.size() > 0) {
10668            if (needSep) pw.println();
10669            needSep = true;
10670            printedAnything = true;
10671            pw.println("  Processes that are on old until the system is ready:");
10672            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10673                    "OnHold Norm", "OnHold PERS", dumpPackage);
10674        }
10675
10676        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10677
10678        if (mProcessCrashTimes.getMap().size() > 0) {
10679            boolean printed = false;
10680            long now = SystemClock.uptimeMillis();
10681            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10682            final int NP = pmap.size();
10683            for (int ip=0; ip<NP; ip++) {
10684                String pname = pmap.keyAt(ip);
10685                SparseArray<Long> uids = pmap.valueAt(ip);
10686                final int N = uids.size();
10687                for (int i=0; i<N; i++) {
10688                    int puid = uids.keyAt(i);
10689                    ProcessRecord r = mProcessNames.get(pname, puid);
10690                    if (dumpPackage != null && (r == null
10691                            || !r.pkgList.containsKey(dumpPackage))) {
10692                        continue;
10693                    }
10694                    if (!printed) {
10695                        if (needSep) pw.println();
10696                        needSep = true;
10697                        pw.println("  Time since processes crashed:");
10698                        printed = true;
10699                        printedAnything = true;
10700                    }
10701                    pw.print("    Process "); pw.print(pname);
10702                            pw.print(" uid "); pw.print(puid);
10703                            pw.print(": last crashed ");
10704                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10705                            pw.println(" ago");
10706                }
10707            }
10708        }
10709
10710        if (mBadProcesses.getMap().size() > 0) {
10711            boolean printed = false;
10712            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10713            final int NP = pmap.size();
10714            for (int ip=0; ip<NP; ip++) {
10715                String pname = pmap.keyAt(ip);
10716                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10717                final int N = uids.size();
10718                for (int i=0; i<N; i++) {
10719                    int puid = uids.keyAt(i);
10720                    ProcessRecord r = mProcessNames.get(pname, puid);
10721                    if (dumpPackage != null && (r == null
10722                            || !r.pkgList.containsKey(dumpPackage))) {
10723                        continue;
10724                    }
10725                    if (!printed) {
10726                        if (needSep) pw.println();
10727                        needSep = true;
10728                        pw.println("  Bad processes:");
10729                        printedAnything = true;
10730                    }
10731                    BadProcessInfo info = uids.valueAt(i);
10732                    pw.print("    Bad process "); pw.print(pname);
10733                            pw.print(" uid "); pw.print(puid);
10734                            pw.print(": crashed at time "); pw.println(info.time);
10735                    if (info.shortMsg != null) {
10736                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10737                    }
10738                    if (info.longMsg != null) {
10739                        pw.print("      Long msg: "); pw.println(info.longMsg);
10740                    }
10741                    if (info.stack != null) {
10742                        pw.println("      Stack:");
10743                        int lastPos = 0;
10744                        for (int pos=0; pos<info.stack.length(); pos++) {
10745                            if (info.stack.charAt(pos) == '\n') {
10746                                pw.print("        ");
10747                                pw.write(info.stack, lastPos, pos-lastPos);
10748                                pw.println();
10749                                lastPos = pos+1;
10750                            }
10751                        }
10752                        if (lastPos < info.stack.length()) {
10753                            pw.print("        ");
10754                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10755                            pw.println();
10756                        }
10757                    }
10758                }
10759            }
10760        }
10761
10762        if (dumpPackage == null) {
10763            pw.println();
10764            needSep = false;
10765            pw.println("  mStartedUsers:");
10766            for (int i=0; i<mStartedUsers.size(); i++) {
10767                UserStartedState uss = mStartedUsers.valueAt(i);
10768                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10769                        pw.print(": "); uss.dump("", pw);
10770            }
10771            pw.print("  mStartedUserArray: [");
10772            for (int i=0; i<mStartedUserArray.length; i++) {
10773                if (i > 0) pw.print(", ");
10774                pw.print(mStartedUserArray[i]);
10775            }
10776            pw.println("]");
10777            pw.print("  mUserLru: [");
10778            for (int i=0; i<mUserLru.size(); i++) {
10779                if (i > 0) pw.print(", ");
10780                pw.print(mUserLru.get(i));
10781            }
10782            pw.println("]");
10783            if (dumpAll) {
10784                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10785            }
10786        }
10787        if (mHomeProcess != null && (dumpPackage == null
10788                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10789            if (needSep) {
10790                pw.println();
10791                needSep = false;
10792            }
10793            pw.println("  mHomeProcess: " + mHomeProcess);
10794        }
10795        if (mPreviousProcess != null && (dumpPackage == null
10796                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10797            if (needSep) {
10798                pw.println();
10799                needSep = false;
10800            }
10801            pw.println("  mPreviousProcess: " + mPreviousProcess);
10802        }
10803        if (dumpAll) {
10804            StringBuilder sb = new StringBuilder(128);
10805            sb.append("  mPreviousProcessVisibleTime: ");
10806            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10807            pw.println(sb);
10808        }
10809        if (mHeavyWeightProcess != null && (dumpPackage == null
10810                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10811            if (needSep) {
10812                pw.println();
10813                needSep = false;
10814            }
10815            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10816        }
10817        if (dumpPackage == null) {
10818            pw.println("  mConfiguration: " + mConfiguration);
10819        }
10820        if (dumpAll) {
10821            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10822            if (mCompatModePackages.getPackages().size() > 0) {
10823                boolean printed = false;
10824                for (Map.Entry<String, Integer> entry
10825                        : mCompatModePackages.getPackages().entrySet()) {
10826                    String pkg = entry.getKey();
10827                    int mode = entry.getValue();
10828                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10829                        continue;
10830                    }
10831                    if (!printed) {
10832                        pw.println("  mScreenCompatPackages:");
10833                        printed = true;
10834                    }
10835                    pw.print("    "); pw.print(pkg); pw.print(": ");
10836                            pw.print(mode); pw.println();
10837                }
10838            }
10839        }
10840        if (dumpPackage == null) {
10841            if (mSleeping || mWentToSleep || mLockScreenShown) {
10842                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10843                        + " mLockScreenShown " + mLockScreenShown);
10844            }
10845            if (mShuttingDown) {
10846                pw.println("  mShuttingDown=" + mShuttingDown);
10847            }
10848        }
10849        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10850                || mOrigWaitForDebugger) {
10851            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10852                    || dumpPackage.equals(mOrigDebugApp)) {
10853                if (needSep) {
10854                    pw.println();
10855                    needSep = false;
10856                }
10857                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10858                        + " mDebugTransient=" + mDebugTransient
10859                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10860            }
10861        }
10862        if (mOpenGlTraceApp != null) {
10863            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10864                if (needSep) {
10865                    pw.println();
10866                    needSep = false;
10867                }
10868                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10869            }
10870        }
10871        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10872                || mProfileFd != null) {
10873            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10874                if (needSep) {
10875                    pw.println();
10876                    needSep = false;
10877                }
10878                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10879                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10880                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10881                        + mAutoStopProfiler);
10882            }
10883        }
10884        if (dumpPackage == null) {
10885            if (mAlwaysFinishActivities || mController != null) {
10886                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10887                        + " mController=" + mController);
10888            }
10889            if (dumpAll) {
10890                pw.println("  Total persistent processes: " + numPers);
10891                pw.println("  mStartRunning=" + mStartRunning
10892                        + " mProcessesReady=" + mProcessesReady
10893                        + " mSystemReady=" + mSystemReady);
10894                pw.println("  mBooting=" + mBooting
10895                        + " mBooted=" + mBooted
10896                        + " mFactoryTest=" + mFactoryTest);
10897                pw.print("  mLastPowerCheckRealtime=");
10898                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10899                        pw.println("");
10900                pw.print("  mLastPowerCheckUptime=");
10901                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10902                        pw.println("");
10903                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10904                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10905                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10906                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10907                        + " (" + mLruProcesses.size() + " total)"
10908                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10909                        + " mNumServiceProcs=" + mNumServiceProcs
10910                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10911                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10912                        + " mLastMemoryLevel" + mLastMemoryLevel
10913                        + " mLastNumProcesses" + mLastNumProcesses);
10914                long now = SystemClock.uptimeMillis();
10915                pw.print("  mLastIdleTime=");
10916                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10917                        pw.print(" mLowRamSinceLastIdle=");
10918                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10919                        pw.println();
10920            }
10921        }
10922
10923        if (!printedAnything) {
10924            pw.println("  (nothing)");
10925        }
10926    }
10927
10928    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10929            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10930        if (mProcessesToGc.size() > 0) {
10931            boolean printed = false;
10932            long now = SystemClock.uptimeMillis();
10933            for (int i=0; i<mProcessesToGc.size(); i++) {
10934                ProcessRecord proc = mProcessesToGc.get(i);
10935                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10936                    continue;
10937                }
10938                if (!printed) {
10939                    if (needSep) pw.println();
10940                    needSep = true;
10941                    pw.println("  Processes that are waiting to GC:");
10942                    printed = true;
10943                }
10944                pw.print("    Process "); pw.println(proc);
10945                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10946                        pw.print(", last gced=");
10947                        pw.print(now-proc.lastRequestedGc);
10948                        pw.print(" ms ago, last lowMem=");
10949                        pw.print(now-proc.lastLowMemory);
10950                        pw.println(" ms ago");
10951
10952            }
10953        }
10954        return needSep;
10955    }
10956
10957    void printOomLevel(PrintWriter pw, String name, int adj) {
10958        pw.print("    ");
10959        if (adj >= 0) {
10960            pw.print(' ');
10961            if (adj < 10) pw.print(' ');
10962        } else {
10963            if (adj > -10) pw.print(' ');
10964        }
10965        pw.print(adj);
10966        pw.print(": ");
10967        pw.print(name);
10968        pw.print(" (");
10969        pw.print(mProcessList.getMemLevel(adj)/1024);
10970        pw.println(" kB)");
10971    }
10972
10973    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10974            int opti, boolean dumpAll) {
10975        boolean needSep = false;
10976
10977        if (mLruProcesses.size() > 0) {
10978            if (needSep) pw.println();
10979            needSep = true;
10980            pw.println("  OOM levels:");
10981            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10982            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10983            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10984            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10985            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10986            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10987            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10988            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10989            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10990            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10991            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10992            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10993            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10994
10995            if (needSep) pw.println();
10996            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10997                    pw.print(" total, non-act at ");
10998                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10999                    pw.print(", non-svc at ");
11000                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11001                    pw.println("):");
11002            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11003            needSep = true;
11004        }
11005
11006        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11007
11008        pw.println();
11009        pw.println("  mHomeProcess: " + mHomeProcess);
11010        pw.println("  mPreviousProcess: " + mPreviousProcess);
11011        if (mHeavyWeightProcess != null) {
11012            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11013        }
11014
11015        return true;
11016    }
11017
11018    /**
11019     * There are three ways to call this:
11020     *  - no provider specified: dump all the providers
11021     *  - a flattened component name that matched an existing provider was specified as the
11022     *    first arg: dump that one provider
11023     *  - the first arg isn't the flattened component name of an existing provider:
11024     *    dump all providers whose component contains the first arg as a substring
11025     */
11026    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11027            int opti, boolean dumpAll) {
11028        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11029    }
11030
11031    static class ItemMatcher {
11032        ArrayList<ComponentName> components;
11033        ArrayList<String> strings;
11034        ArrayList<Integer> objects;
11035        boolean all;
11036
11037        ItemMatcher() {
11038            all = true;
11039        }
11040
11041        void build(String name) {
11042            ComponentName componentName = ComponentName.unflattenFromString(name);
11043            if (componentName != null) {
11044                if (components == null) {
11045                    components = new ArrayList<ComponentName>();
11046                }
11047                components.add(componentName);
11048                all = false;
11049            } else {
11050                int objectId = 0;
11051                // Not a '/' separated full component name; maybe an object ID?
11052                try {
11053                    objectId = Integer.parseInt(name, 16);
11054                    if (objects == null) {
11055                        objects = new ArrayList<Integer>();
11056                    }
11057                    objects.add(objectId);
11058                    all = false;
11059                } catch (RuntimeException e) {
11060                    // Not an integer; just do string match.
11061                    if (strings == null) {
11062                        strings = new ArrayList<String>();
11063                    }
11064                    strings.add(name);
11065                    all = false;
11066                }
11067            }
11068        }
11069
11070        int build(String[] args, int opti) {
11071            for (; opti<args.length; opti++) {
11072                String name = args[opti];
11073                if ("--".equals(name)) {
11074                    return opti+1;
11075                }
11076                build(name);
11077            }
11078            return opti;
11079        }
11080
11081        boolean match(Object object, ComponentName comp) {
11082            if (all) {
11083                return true;
11084            }
11085            if (components != null) {
11086                for (int i=0; i<components.size(); i++) {
11087                    if (components.get(i).equals(comp)) {
11088                        return true;
11089                    }
11090                }
11091            }
11092            if (objects != null) {
11093                for (int i=0; i<objects.size(); i++) {
11094                    if (System.identityHashCode(object) == objects.get(i)) {
11095                        return true;
11096                    }
11097                }
11098            }
11099            if (strings != null) {
11100                String flat = comp.flattenToString();
11101                for (int i=0; i<strings.size(); i++) {
11102                    if (flat.contains(strings.get(i))) {
11103                        return true;
11104                    }
11105                }
11106            }
11107            return false;
11108        }
11109    }
11110
11111    /**
11112     * There are three things that cmd can be:
11113     *  - a flattened component name that matches an existing activity
11114     *  - the cmd arg isn't the flattened component name of an existing activity:
11115     *    dump all activity whose component contains the cmd as a substring
11116     *  - A hex number of the ActivityRecord object instance.
11117     */
11118    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11119            int opti, boolean dumpAll) {
11120        ArrayList<ActivityRecord> activities;
11121
11122        synchronized (this) {
11123            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11124        }
11125
11126        if (activities.size() <= 0) {
11127            return false;
11128        }
11129
11130        String[] newArgs = new String[args.length - opti];
11131        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11132
11133        TaskRecord lastTask = null;
11134        boolean needSep = false;
11135        for (int i=activities.size()-1; i>=0; i--) {
11136            ActivityRecord r = activities.get(i);
11137            if (needSep) {
11138                pw.println();
11139            }
11140            needSep = true;
11141            synchronized (this) {
11142                if (lastTask != r.task) {
11143                    lastTask = r.task;
11144                    pw.print("TASK "); pw.print(lastTask.affinity);
11145                            pw.print(" id="); pw.println(lastTask.taskId);
11146                    if (dumpAll) {
11147                        lastTask.dump(pw, "  ");
11148                    }
11149                }
11150            }
11151            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11152        }
11153        return true;
11154    }
11155
11156    /**
11157     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11158     * there is a thread associated with the activity.
11159     */
11160    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11161            final ActivityRecord r, String[] args, boolean dumpAll) {
11162        String innerPrefix = prefix + "  ";
11163        synchronized (this) {
11164            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11165                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11166                    pw.print(" pid=");
11167                    if (r.app != null) pw.println(r.app.pid);
11168                    else pw.println("(not running)");
11169            if (dumpAll) {
11170                r.dump(pw, innerPrefix);
11171            }
11172        }
11173        if (r.app != null && r.app.thread != null) {
11174            // flush anything that is already in the PrintWriter since the thread is going
11175            // to write to the file descriptor directly
11176            pw.flush();
11177            try {
11178                TransferPipe tp = new TransferPipe();
11179                try {
11180                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11181                            r.appToken, innerPrefix, args);
11182                    tp.go(fd);
11183                } finally {
11184                    tp.kill();
11185                }
11186            } catch (IOException e) {
11187                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11188            } catch (RemoteException e) {
11189                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11190            }
11191        }
11192    }
11193
11194    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11195            int opti, boolean dumpAll, String dumpPackage) {
11196        boolean needSep = false;
11197        boolean onlyHistory = false;
11198        boolean printedAnything = false;
11199
11200        if ("history".equals(dumpPackage)) {
11201            if (opti < args.length && "-s".equals(args[opti])) {
11202                dumpAll = false;
11203            }
11204            onlyHistory = true;
11205            dumpPackage = null;
11206        }
11207
11208        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11209        if (!onlyHistory && dumpAll) {
11210            if (mRegisteredReceivers.size() > 0) {
11211                boolean printed = false;
11212                Iterator it = mRegisteredReceivers.values().iterator();
11213                while (it.hasNext()) {
11214                    ReceiverList r = (ReceiverList)it.next();
11215                    if (dumpPackage != null && (r.app == null ||
11216                            !dumpPackage.equals(r.app.info.packageName))) {
11217                        continue;
11218                    }
11219                    if (!printed) {
11220                        pw.println("  Registered Receivers:");
11221                        needSep = true;
11222                        printed = true;
11223                        printedAnything = true;
11224                    }
11225                    pw.print("  * "); pw.println(r);
11226                    r.dump(pw, "    ");
11227                }
11228            }
11229
11230            if (mReceiverResolver.dump(pw, needSep ?
11231                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11232                    "    ", dumpPackage, false)) {
11233                needSep = true;
11234                printedAnything = true;
11235            }
11236        }
11237
11238        for (BroadcastQueue q : mBroadcastQueues) {
11239            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11240            printedAnything |= needSep;
11241        }
11242
11243        needSep = true;
11244
11245        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11246            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11247                if (needSep) {
11248                    pw.println();
11249                }
11250                needSep = true;
11251                printedAnything = true;
11252                pw.print("  Sticky broadcasts for user ");
11253                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11254                StringBuilder sb = new StringBuilder(128);
11255                for (Map.Entry<String, ArrayList<Intent>> ent
11256                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11257                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11258                    if (dumpAll) {
11259                        pw.println(":");
11260                        ArrayList<Intent> intents = ent.getValue();
11261                        final int N = intents.size();
11262                        for (int i=0; i<N; i++) {
11263                            sb.setLength(0);
11264                            sb.append("    Intent: ");
11265                            intents.get(i).toShortString(sb, false, true, false, false);
11266                            pw.println(sb.toString());
11267                            Bundle bundle = intents.get(i).getExtras();
11268                            if (bundle != null) {
11269                                pw.print("      ");
11270                                pw.println(bundle.toString());
11271                            }
11272                        }
11273                    } else {
11274                        pw.println("");
11275                    }
11276                }
11277            }
11278        }
11279
11280        if (!onlyHistory && dumpAll) {
11281            pw.println();
11282            for (BroadcastQueue queue : mBroadcastQueues) {
11283                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11284                        + queue.mBroadcastsScheduled);
11285            }
11286            pw.println("  mHandler:");
11287            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11288            needSep = true;
11289            printedAnything = true;
11290        }
11291
11292        if (!printedAnything) {
11293            pw.println("  (nothing)");
11294        }
11295    }
11296
11297    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11298            int opti, boolean dumpAll, String dumpPackage) {
11299        boolean needSep;
11300        boolean printedAnything = false;
11301
11302        ItemMatcher matcher = new ItemMatcher();
11303        matcher.build(args, opti);
11304
11305        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11306
11307        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11308        printedAnything |= needSep;
11309
11310        if (mLaunchingProviders.size() > 0) {
11311            boolean printed = false;
11312            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11313                ContentProviderRecord r = mLaunchingProviders.get(i);
11314                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11315                    continue;
11316                }
11317                if (!printed) {
11318                    if (needSep) pw.println();
11319                    needSep = true;
11320                    pw.println("  Launching content providers:");
11321                    printed = true;
11322                    printedAnything = true;
11323                }
11324                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11325                        pw.println(r);
11326            }
11327        }
11328
11329        if (mGrantedUriPermissions.size() > 0) {
11330            boolean printed = false;
11331            int dumpUid = -2;
11332            if (dumpPackage != null) {
11333                try {
11334                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11335                } catch (NameNotFoundException e) {
11336                    dumpUid = -1;
11337                }
11338            }
11339            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11340                int uid = mGrantedUriPermissions.keyAt(i);
11341                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11342                    continue;
11343                }
11344                ArrayMap<Uri, UriPermission> perms
11345                        = mGrantedUriPermissions.valueAt(i);
11346                if (!printed) {
11347                    if (needSep) pw.println();
11348                    needSep = true;
11349                    pw.println("  Granted Uri Permissions:");
11350                    printed = true;
11351                    printedAnything = true;
11352                }
11353                pw.print("  * UID "); pw.print(uid);
11354                        pw.println(" holds:");
11355                for (UriPermission perm : perms.values()) {
11356                    pw.print("    "); pw.println(perm);
11357                    if (dumpAll) {
11358                        perm.dump(pw, "      ");
11359                    }
11360                }
11361            }
11362        }
11363
11364        if (!printedAnything) {
11365            pw.println("  (nothing)");
11366        }
11367    }
11368
11369    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11370            int opti, boolean dumpAll, String dumpPackage) {
11371        boolean printed = false;
11372
11373        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11374
11375        if (mIntentSenderRecords.size() > 0) {
11376            Iterator<WeakReference<PendingIntentRecord>> it
11377                    = mIntentSenderRecords.values().iterator();
11378            while (it.hasNext()) {
11379                WeakReference<PendingIntentRecord> ref = it.next();
11380                PendingIntentRecord rec = ref != null ? ref.get(): null;
11381                if (dumpPackage != null && (rec == null
11382                        || !dumpPackage.equals(rec.key.packageName))) {
11383                    continue;
11384                }
11385                printed = true;
11386                if (rec != null) {
11387                    pw.print("  * "); pw.println(rec);
11388                    if (dumpAll) {
11389                        rec.dump(pw, "    ");
11390                    }
11391                } else {
11392                    pw.print("  * "); pw.println(ref);
11393                }
11394            }
11395        }
11396
11397        if (!printed) {
11398            pw.println("  (nothing)");
11399        }
11400    }
11401
11402    private static final int dumpProcessList(PrintWriter pw,
11403            ActivityManagerService service, List list,
11404            String prefix, String normalLabel, String persistentLabel,
11405            String dumpPackage) {
11406        int numPers = 0;
11407        final int N = list.size()-1;
11408        for (int i=N; i>=0; i--) {
11409            ProcessRecord r = (ProcessRecord)list.get(i);
11410            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11411                continue;
11412            }
11413            pw.println(String.format("%s%s #%2d: %s",
11414                    prefix, (r.persistent ? persistentLabel : normalLabel),
11415                    i, r.toString()));
11416            if (r.persistent) {
11417                numPers++;
11418            }
11419        }
11420        return numPers;
11421    }
11422
11423    private static final boolean dumpProcessOomList(PrintWriter pw,
11424            ActivityManagerService service, List<ProcessRecord> origList,
11425            String prefix, String normalLabel, String persistentLabel,
11426            boolean inclDetails, String dumpPackage) {
11427
11428        ArrayList<Pair<ProcessRecord, Integer>> list
11429                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11430        for (int i=0; i<origList.size(); i++) {
11431            ProcessRecord r = origList.get(i);
11432            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11433                continue;
11434            }
11435            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11436        }
11437
11438        if (list.size() <= 0) {
11439            return false;
11440        }
11441
11442        Comparator<Pair<ProcessRecord, Integer>> comparator
11443                = new Comparator<Pair<ProcessRecord, Integer>>() {
11444            @Override
11445            public int compare(Pair<ProcessRecord, Integer> object1,
11446                    Pair<ProcessRecord, Integer> object2) {
11447                if (object1.first.setAdj != object2.first.setAdj) {
11448                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11449                }
11450                if (object1.second.intValue() != object2.second.intValue()) {
11451                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11452                }
11453                return 0;
11454            }
11455        };
11456
11457        Collections.sort(list, comparator);
11458
11459        final long curRealtime = SystemClock.elapsedRealtime();
11460        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11461        final long curUptime = SystemClock.uptimeMillis();
11462        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11463
11464        for (int i=list.size()-1; i>=0; i--) {
11465            ProcessRecord r = list.get(i).first;
11466            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11467            char schedGroup;
11468            switch (r.setSchedGroup) {
11469                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11470                    schedGroup = 'B';
11471                    break;
11472                case Process.THREAD_GROUP_DEFAULT:
11473                    schedGroup = 'F';
11474                    break;
11475                default:
11476                    schedGroup = '?';
11477                    break;
11478            }
11479            char foreground;
11480            if (r.foregroundActivities) {
11481                foreground = 'A';
11482            } else if (r.foregroundServices) {
11483                foreground = 'S';
11484            } else {
11485                foreground = ' ';
11486            }
11487            String procState = ProcessList.makeProcStateString(r.curProcState);
11488            pw.print(prefix);
11489            pw.print(r.persistent ? persistentLabel : normalLabel);
11490            pw.print(" #");
11491            int num = (origList.size()-1)-list.get(i).second;
11492            if (num < 10) pw.print(' ');
11493            pw.print(num);
11494            pw.print(": ");
11495            pw.print(oomAdj);
11496            pw.print(' ');
11497            pw.print(schedGroup);
11498            pw.print('/');
11499            pw.print(foreground);
11500            pw.print('/');
11501            pw.print(procState);
11502            pw.print(" trm:");
11503            if (r.trimMemoryLevel < 10) pw.print(' ');
11504            pw.print(r.trimMemoryLevel);
11505            pw.print(' ');
11506            pw.print(r.toShortString());
11507            pw.print(" (");
11508            pw.print(r.adjType);
11509            pw.println(')');
11510            if (r.adjSource != null || r.adjTarget != null) {
11511                pw.print(prefix);
11512                pw.print("    ");
11513                if (r.adjTarget instanceof ComponentName) {
11514                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11515                } else if (r.adjTarget != null) {
11516                    pw.print(r.adjTarget.toString());
11517                } else {
11518                    pw.print("{null}");
11519                }
11520                pw.print("<=");
11521                if (r.adjSource instanceof ProcessRecord) {
11522                    pw.print("Proc{");
11523                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11524                    pw.println("}");
11525                } else if (r.adjSource != null) {
11526                    pw.println(r.adjSource.toString());
11527                } else {
11528                    pw.println("{null}");
11529                }
11530            }
11531            if (inclDetails) {
11532                pw.print(prefix);
11533                pw.print("    ");
11534                pw.print("oom: max="); pw.print(r.maxAdj);
11535                pw.print(" curRaw="); pw.print(r.curRawAdj);
11536                pw.print(" setRaw="); pw.print(r.setRawAdj);
11537                pw.print(" cur="); pw.print(r.curAdj);
11538                pw.print(" set="); pw.println(r.setAdj);
11539                pw.print(prefix);
11540                pw.print("    ");
11541                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11542                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11543                pw.print(" lastPss="); pw.print(r.lastPss);
11544                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11545                pw.print(prefix);
11546                pw.print("    ");
11547                pw.print("keeping="); pw.print(r.keeping);
11548                pw.print(" cached="); pw.print(r.cached);
11549                pw.print(" empty="); pw.print(r.empty);
11550                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11551
11552                if (!r.keeping) {
11553                    if (r.lastWakeTime != 0) {
11554                        long wtime;
11555                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11556                        synchronized (stats) {
11557                            wtime = stats.getProcessWakeTime(r.info.uid,
11558                                    r.pid, curRealtime);
11559                        }
11560                        long timeUsed = wtime - r.lastWakeTime;
11561                        pw.print(prefix);
11562                        pw.print("    ");
11563                        pw.print("keep awake over ");
11564                        TimeUtils.formatDuration(realtimeSince, pw);
11565                        pw.print(" used ");
11566                        TimeUtils.formatDuration(timeUsed, pw);
11567                        pw.print(" (");
11568                        pw.print((timeUsed*100)/realtimeSince);
11569                        pw.println("%)");
11570                    }
11571                    if (r.lastCpuTime != 0) {
11572                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11573                        pw.print(prefix);
11574                        pw.print("    ");
11575                        pw.print("run cpu over ");
11576                        TimeUtils.formatDuration(uptimeSince, pw);
11577                        pw.print(" used ");
11578                        TimeUtils.formatDuration(timeUsed, pw);
11579                        pw.print(" (");
11580                        pw.print((timeUsed*100)/uptimeSince);
11581                        pw.println("%)");
11582                    }
11583                }
11584            }
11585        }
11586        return true;
11587    }
11588
11589    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11590        ArrayList<ProcessRecord> procs;
11591        synchronized (this) {
11592            if (args != null && args.length > start
11593                    && args[start].charAt(0) != '-') {
11594                procs = new ArrayList<ProcessRecord>();
11595                int pid = -1;
11596                try {
11597                    pid = Integer.parseInt(args[start]);
11598                } catch (NumberFormatException e) {
11599                }
11600                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11601                    ProcessRecord proc = mLruProcesses.get(i);
11602                    if (proc.pid == pid) {
11603                        procs.add(proc);
11604                    } else if (proc.processName.equals(args[start])) {
11605                        procs.add(proc);
11606                    }
11607                }
11608                if (procs.size() <= 0) {
11609                    return null;
11610                }
11611            } else {
11612                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11613            }
11614        }
11615        return procs;
11616    }
11617
11618    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11619            PrintWriter pw, String[] args) {
11620        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11621        if (procs == null) {
11622            pw.println("No process found for: " + args[0]);
11623            return;
11624        }
11625
11626        long uptime = SystemClock.uptimeMillis();
11627        long realtime = SystemClock.elapsedRealtime();
11628        pw.println("Applications Graphics Acceleration Info:");
11629        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11630
11631        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11632            ProcessRecord r = procs.get(i);
11633            if (r.thread != null) {
11634                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11635                pw.flush();
11636                try {
11637                    TransferPipe tp = new TransferPipe();
11638                    try {
11639                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11640                        tp.go(fd);
11641                    } finally {
11642                        tp.kill();
11643                    }
11644                } catch (IOException e) {
11645                    pw.println("Failure while dumping the app: " + r);
11646                    pw.flush();
11647                } catch (RemoteException e) {
11648                    pw.println("Got a RemoteException while dumping the app " + r);
11649                    pw.flush();
11650                }
11651            }
11652        }
11653    }
11654
11655    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11656        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11657        if (procs == null) {
11658            pw.println("No process found for: " + args[0]);
11659            return;
11660        }
11661
11662        pw.println("Applications Database Info:");
11663
11664        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11665            ProcessRecord r = procs.get(i);
11666            if (r.thread != null) {
11667                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11668                pw.flush();
11669                try {
11670                    TransferPipe tp = new TransferPipe();
11671                    try {
11672                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11673                        tp.go(fd);
11674                    } finally {
11675                        tp.kill();
11676                    }
11677                } catch (IOException e) {
11678                    pw.println("Failure while dumping the app: " + r);
11679                    pw.flush();
11680                } catch (RemoteException e) {
11681                    pw.println("Got a RemoteException while dumping the app " + r);
11682                    pw.flush();
11683                }
11684            }
11685        }
11686    }
11687
11688    final static class MemItem {
11689        final boolean isProc;
11690        final String label;
11691        final String shortLabel;
11692        final long pss;
11693        final int id;
11694        final boolean hasActivities;
11695        ArrayList<MemItem> subitems;
11696
11697        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11698                boolean _hasActivities) {
11699            isProc = true;
11700            label = _label;
11701            shortLabel = _shortLabel;
11702            pss = _pss;
11703            id = _id;
11704            hasActivities = _hasActivities;
11705        }
11706
11707        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11708            isProc = false;
11709            label = _label;
11710            shortLabel = _shortLabel;
11711            pss = _pss;
11712            id = _id;
11713            hasActivities = false;
11714        }
11715    }
11716
11717    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11718            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11719        if (sort && !isCompact) {
11720            Collections.sort(items, new Comparator<MemItem>() {
11721                @Override
11722                public int compare(MemItem lhs, MemItem rhs) {
11723                    if (lhs.pss < rhs.pss) {
11724                        return 1;
11725                    } else if (lhs.pss > rhs.pss) {
11726                        return -1;
11727                    }
11728                    return 0;
11729                }
11730            });
11731        }
11732
11733        for (int i=0; i<items.size(); i++) {
11734            MemItem mi = items.get(i);
11735            if (!isCompact) {
11736                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11737            } else if (mi.isProc) {
11738                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11739                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11740                pw.println(mi.hasActivities ? ",a" : ",e");
11741            } else {
11742                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11743                pw.println(mi.pss);
11744            }
11745            if (mi.subitems != null) {
11746                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11747                        true, isCompact);
11748            }
11749        }
11750    }
11751
11752    // These are in KB.
11753    static final long[] DUMP_MEM_BUCKETS = new long[] {
11754        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11755        120*1024, 160*1024, 200*1024,
11756        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11757        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11758    };
11759
11760    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11761            boolean stackLike) {
11762        int start = label.lastIndexOf('.');
11763        if (start >= 0) start++;
11764        else start = 0;
11765        int end = label.length();
11766        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11767            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11768                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11769                out.append(bucket);
11770                out.append(stackLike ? "MB." : "MB ");
11771                out.append(label, start, end);
11772                return;
11773            }
11774        }
11775        out.append(memKB/1024);
11776        out.append(stackLike ? "MB." : "MB ");
11777        out.append(label, start, end);
11778    }
11779
11780    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11781            ProcessList.NATIVE_ADJ,
11782            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11783            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11784            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11785            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11786            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11787    };
11788    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11789            "Native",
11790            "System", "Persistent", "Foreground",
11791            "Visible", "Perceptible",
11792            "Heavy Weight", "Backup",
11793            "A Services", "Home",
11794            "Previous", "B Services", "Cached"
11795    };
11796    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11797            "native",
11798            "sys", "pers", "fore",
11799            "vis", "percept",
11800            "heavy", "backup",
11801            "servicea", "home",
11802            "prev", "serviceb", "cached"
11803    };
11804
11805    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11806            long realtime, boolean isCheckinRequest, boolean isCompact) {
11807        if (isCheckinRequest || isCompact) {
11808            // short checkin version
11809            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11810        } else {
11811            pw.println("Applications Memory Usage (kB):");
11812            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11813        }
11814    }
11815
11816    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11817            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11818        boolean dumpDetails = false;
11819        boolean dumpFullDetails = false;
11820        boolean dumpDalvik = false;
11821        boolean oomOnly = false;
11822        boolean isCompact = false;
11823        boolean localOnly = false;
11824
11825        int opti = 0;
11826        while (opti < args.length) {
11827            String opt = args[opti];
11828            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11829                break;
11830            }
11831            opti++;
11832            if ("-a".equals(opt)) {
11833                dumpDetails = true;
11834                dumpFullDetails = true;
11835                dumpDalvik = true;
11836            } else if ("-d".equals(opt)) {
11837                dumpDalvik = true;
11838            } else if ("-c".equals(opt)) {
11839                isCompact = true;
11840            } else if ("--oom".equals(opt)) {
11841                oomOnly = true;
11842            } else if ("--local".equals(opt)) {
11843                localOnly = true;
11844            } else if ("-h".equals(opt)) {
11845                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11846                pw.println("  -a: include all available information for each process.");
11847                pw.println("  -d: include dalvik details when dumping process details.");
11848                pw.println("  -c: dump in a compact machine-parseable representation.");
11849                pw.println("  --oom: only show processes organized by oom adj.");
11850                pw.println("  --local: only collect details locally, don't call process.");
11851                pw.println("If [process] is specified it can be the name or ");
11852                pw.println("pid of a specific process to dump.");
11853                return;
11854            } else {
11855                pw.println("Unknown argument: " + opt + "; use -h for help");
11856            }
11857        }
11858
11859        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11860        long uptime = SystemClock.uptimeMillis();
11861        long realtime = SystemClock.elapsedRealtime();
11862        final long[] tmpLong = new long[1];
11863
11864        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11865        if (procs == null) {
11866            // No Java processes.  Maybe they want to print a native process.
11867            if (args != null && args.length > opti
11868                    && args[opti].charAt(0) != '-') {
11869                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11870                        = new ArrayList<ProcessCpuTracker.Stats>();
11871                updateCpuStatsNow();
11872                int findPid = -1;
11873                try {
11874                    findPid = Integer.parseInt(args[opti]);
11875                } catch (NumberFormatException e) {
11876                }
11877                synchronized (mProcessCpuThread) {
11878                    final int N = mProcessCpuTracker.countStats();
11879                    for (int i=0; i<N; i++) {
11880                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11881                        if (st.pid == findPid || (st.baseName != null
11882                                && st.baseName.equals(args[opti]))) {
11883                            nativeProcs.add(st);
11884                        }
11885                    }
11886                }
11887                if (nativeProcs.size() > 0) {
11888                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11889                            isCompact);
11890                    Debug.MemoryInfo mi = null;
11891                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11892                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11893                        final int pid = r.pid;
11894                        if (!isCheckinRequest && dumpDetails) {
11895                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11896                        }
11897                        if (mi == null) {
11898                            mi = new Debug.MemoryInfo();
11899                        }
11900                        if (dumpDetails || (!brief && !oomOnly)) {
11901                            Debug.getMemoryInfo(pid, mi);
11902                        } else {
11903                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11904                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11905                        }
11906                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11907                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11908                        if (isCheckinRequest) {
11909                            pw.println();
11910                        }
11911                    }
11912                    return;
11913                }
11914            }
11915            pw.println("No process found for: " + args[opti]);
11916            return;
11917        }
11918
11919        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11920            dumpDetails = true;
11921        }
11922
11923        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11924
11925        String[] innerArgs = new String[args.length-opti];
11926        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11927
11928        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11929        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11930        long nativePss=0, dalvikPss=0, otherPss=0;
11931        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11932
11933        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11934        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11935                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11936
11937        long totalPss = 0;
11938        long cachedPss = 0;
11939
11940        Debug.MemoryInfo mi = null;
11941        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11942            final ProcessRecord r = procs.get(i);
11943            final IApplicationThread thread;
11944            final int pid;
11945            final int oomAdj;
11946            final boolean hasActivities;
11947            synchronized (this) {
11948                thread = r.thread;
11949                pid = r.pid;
11950                oomAdj = r.getSetAdjWithServices();
11951                hasActivities = r.activities.size() > 0;
11952            }
11953            if (thread != null) {
11954                if (!isCheckinRequest && dumpDetails) {
11955                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11956                }
11957                if (mi == null) {
11958                    mi = new Debug.MemoryInfo();
11959                }
11960                if (dumpDetails || (!brief && !oomOnly)) {
11961                    Debug.getMemoryInfo(pid, mi);
11962                } else {
11963                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11964                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11965                }
11966                if (dumpDetails) {
11967                    if (localOnly) {
11968                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11969                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11970                        if (isCheckinRequest) {
11971                            pw.println();
11972                        }
11973                    } else {
11974                        try {
11975                            pw.flush();
11976                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11977                                    dumpDalvik, innerArgs);
11978                        } catch (RemoteException e) {
11979                            if (!isCheckinRequest) {
11980                                pw.println("Got RemoteException!");
11981                                pw.flush();
11982                            }
11983                        }
11984                    }
11985                }
11986
11987                final long myTotalPss = mi.getTotalPss();
11988                final long myTotalUss = mi.getTotalUss();
11989
11990                synchronized (this) {
11991                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11992                        // Record this for posterity if the process has been stable.
11993                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11994                    }
11995                }
11996
11997                if (!isCheckinRequest && mi != null) {
11998                    totalPss += myTotalPss;
11999                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12000                            (hasActivities ? " / activities)" : ")"),
12001                            r.processName, myTotalPss, pid, hasActivities);
12002                    procMems.add(pssItem);
12003                    procMemsMap.put(pid, pssItem);
12004
12005                    nativePss += mi.nativePss;
12006                    dalvikPss += mi.dalvikPss;
12007                    otherPss += mi.otherPss;
12008                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12009                        long mem = mi.getOtherPss(j);
12010                        miscPss[j] += mem;
12011                        otherPss -= mem;
12012                    }
12013
12014                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12015                        cachedPss += myTotalPss;
12016                    }
12017
12018                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12019                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12020                                || oomIndex == (oomPss.length-1)) {
12021                            oomPss[oomIndex] += myTotalPss;
12022                            if (oomProcs[oomIndex] == null) {
12023                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12024                            }
12025                            oomProcs[oomIndex].add(pssItem);
12026                            break;
12027                        }
12028                    }
12029                }
12030            }
12031        }
12032
12033        if (!isCheckinRequest && procs.size() > 1) {
12034            // If we are showing aggregations, also look for native processes to
12035            // include so that our aggregations are more accurate.
12036            updateCpuStatsNow();
12037            synchronized (mProcessCpuThread) {
12038                final int N = mProcessCpuTracker.countStats();
12039                for (int i=0; i<N; i++) {
12040                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12041                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12042                        if (mi == null) {
12043                            mi = new Debug.MemoryInfo();
12044                        }
12045                        if (!brief && !oomOnly) {
12046                            Debug.getMemoryInfo(st.pid, mi);
12047                        } else {
12048                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12049                            mi.nativePrivateDirty = (int)tmpLong[0];
12050                        }
12051
12052                        final long myTotalPss = mi.getTotalPss();
12053                        totalPss += myTotalPss;
12054
12055                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12056                                st.name, myTotalPss, st.pid, false);
12057                        procMems.add(pssItem);
12058
12059                        nativePss += mi.nativePss;
12060                        dalvikPss += mi.dalvikPss;
12061                        otherPss += mi.otherPss;
12062                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12063                            long mem = mi.getOtherPss(j);
12064                            miscPss[j] += mem;
12065                            otherPss -= mem;
12066                        }
12067                        oomPss[0] += myTotalPss;
12068                        if (oomProcs[0] == null) {
12069                            oomProcs[0] = new ArrayList<MemItem>();
12070                        }
12071                        oomProcs[0].add(pssItem);
12072                    }
12073                }
12074            }
12075
12076            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12077
12078            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12079            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12080            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12081            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12082                String label = Debug.MemoryInfo.getOtherLabel(j);
12083                catMems.add(new MemItem(label, label, miscPss[j], j));
12084            }
12085
12086            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12087            for (int j=0; j<oomPss.length; j++) {
12088                if (oomPss[j] != 0) {
12089                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12090                            : DUMP_MEM_OOM_LABEL[j];
12091                    MemItem item = new MemItem(label, label, oomPss[j],
12092                            DUMP_MEM_OOM_ADJ[j]);
12093                    item.subitems = oomProcs[j];
12094                    oomMems.add(item);
12095                }
12096            }
12097
12098            if (!brief && !oomOnly && !isCompact) {
12099                pw.println();
12100                pw.println("Total PSS by process:");
12101                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12102                pw.println();
12103            }
12104            if (!isCompact) {
12105                pw.println("Total PSS by OOM adjustment:");
12106            }
12107            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12108            if (!brief && !oomOnly) {
12109                PrintWriter out = categoryPw != null ? categoryPw : pw;
12110                if (!isCompact) {
12111                    out.println();
12112                    out.println("Total PSS by category:");
12113                }
12114                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12115            }
12116            if (!isCompact) {
12117                pw.println();
12118            }
12119            MemInfoReader memInfo = new MemInfoReader();
12120            memInfo.readMemInfo();
12121            if (!brief) {
12122                if (!isCompact) {
12123                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12124                    pw.println(" kB");
12125                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12126                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12127                            pw.print(cachedPss); pw.print(" cached pss + ");
12128                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12129                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12130                } else {
12131                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12132                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12133                            + memInfo.getFreeSizeKb()); pw.print(",");
12134                    pw.println(totalPss - cachedPss);
12135                }
12136            }
12137            if (!isCompact) {
12138                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12139                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12140                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12141                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12142                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12143                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12144                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12145                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12146                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12147                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12148                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12149            }
12150            if (!brief) {
12151                if (memInfo.getZramTotalSizeKb() != 0) {
12152                    if (!isCompact) {
12153                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12154                                pw.print(" kB physical used for ");
12155                                pw.print(memInfo.getSwapTotalSizeKb()
12156                                        - memInfo.getSwapFreeSizeKb());
12157                                pw.print(" kB in swap (");
12158                                pw.print(memInfo.getSwapTotalSizeKb());
12159                                pw.println(" kB total swap)");
12160                    } else {
12161                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12162                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12163                                pw.println(memInfo.getSwapFreeSizeKb());
12164                    }
12165                }
12166                final int[] SINGLE_LONG_FORMAT = new int[] {
12167                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12168                };
12169                long[] longOut = new long[1];
12170                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12171                        SINGLE_LONG_FORMAT, null, longOut, null);
12172                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12173                longOut[0] = 0;
12174                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12175                        SINGLE_LONG_FORMAT, null, longOut, null);
12176                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12177                longOut[0] = 0;
12178                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12179                        SINGLE_LONG_FORMAT, null, longOut, null);
12180                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12181                longOut[0] = 0;
12182                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12183                        SINGLE_LONG_FORMAT, null, longOut, null);
12184                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12185                if (!isCompact) {
12186                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12187                        pw.print("      KSM: "); pw.print(sharing);
12188                                pw.print(" kB saved from shared ");
12189                                pw.print(shared); pw.println(" kB");
12190                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12191                                pw.print(voltile); pw.println(" kB volatile");
12192                    }
12193                    pw.print("   Tuning: ");
12194                    pw.print(ActivityManager.staticGetMemoryClass());
12195                    pw.print(" (large ");
12196                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12197                    pw.print("), oom ");
12198                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12199                    pw.print(" kB");
12200                    pw.print(", restore limit ");
12201                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12202                    pw.print(" kB");
12203                    if (ActivityManager.isLowRamDeviceStatic()) {
12204                        pw.print(" (low-ram)");
12205                    }
12206                    if (ActivityManager.isHighEndGfx()) {
12207                        pw.print(" (high-end-gfx)");
12208                    }
12209                    pw.println();
12210                } else {
12211                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12212                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12213                    pw.println(voltile);
12214                    pw.print("tuning,");
12215                    pw.print(ActivityManager.staticGetMemoryClass());
12216                    pw.print(',');
12217                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12218                    pw.print(',');
12219                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12220                    if (ActivityManager.isLowRamDeviceStatic()) {
12221                        pw.print(",low-ram");
12222                    }
12223                    if (ActivityManager.isHighEndGfx()) {
12224                        pw.print(",high-end-gfx");
12225                    }
12226                    pw.println();
12227                }
12228            }
12229        }
12230    }
12231
12232    /**
12233     * Searches array of arguments for the specified string
12234     * @param args array of argument strings
12235     * @param value value to search for
12236     * @return true if the value is contained in the array
12237     */
12238    private static boolean scanArgs(String[] args, String value) {
12239        if (args != null) {
12240            for (String arg : args) {
12241                if (value.equals(arg)) {
12242                    return true;
12243                }
12244            }
12245        }
12246        return false;
12247    }
12248
12249    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12250            ContentProviderRecord cpr, boolean always) {
12251        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12252
12253        if (!inLaunching || always) {
12254            synchronized (cpr) {
12255                cpr.launchingApp = null;
12256                cpr.notifyAll();
12257            }
12258            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12259            String names[] = cpr.info.authority.split(";");
12260            for (int j = 0; j < names.length; j++) {
12261                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12262            }
12263        }
12264
12265        for (int i=0; i<cpr.connections.size(); i++) {
12266            ContentProviderConnection conn = cpr.connections.get(i);
12267            if (conn.waiting) {
12268                // If this connection is waiting for the provider, then we don't
12269                // need to mess with its process unless we are always removing
12270                // or for some reason the provider is not currently launching.
12271                if (inLaunching && !always) {
12272                    continue;
12273                }
12274            }
12275            ProcessRecord capp = conn.client;
12276            conn.dead = true;
12277            if (conn.stableCount > 0) {
12278                if (!capp.persistent && capp.thread != null
12279                        && capp.pid != 0
12280                        && capp.pid != MY_PID) {
12281                    killUnneededProcessLocked(capp, "depends on provider "
12282                            + cpr.name.flattenToShortString()
12283                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12284                }
12285            } else if (capp.thread != null && conn.provider.provider != null) {
12286                try {
12287                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12288                } catch (RemoteException e) {
12289                }
12290                // In the protocol here, we don't expect the client to correctly
12291                // clean up this connection, we'll just remove it.
12292                cpr.connections.remove(i);
12293                conn.client.conProviders.remove(conn);
12294            }
12295        }
12296
12297        if (inLaunching && always) {
12298            mLaunchingProviders.remove(cpr);
12299        }
12300        return inLaunching;
12301    }
12302
12303    /**
12304     * Main code for cleaning up a process when it has gone away.  This is
12305     * called both as a result of the process dying, or directly when stopping
12306     * a process when running in single process mode.
12307     */
12308    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12309            boolean restarting, boolean allowRestart, int index) {
12310        if (index >= 0) {
12311            removeLruProcessLocked(app);
12312            ProcessList.remove(app.pid);
12313        }
12314
12315        mProcessesToGc.remove(app);
12316        mPendingPssProcesses.remove(app);
12317
12318        // Dismiss any open dialogs.
12319        if (app.crashDialog != null && !app.forceCrashReport) {
12320            app.crashDialog.dismiss();
12321            app.crashDialog = null;
12322        }
12323        if (app.anrDialog != null) {
12324            app.anrDialog.dismiss();
12325            app.anrDialog = null;
12326        }
12327        if (app.waitDialog != null) {
12328            app.waitDialog.dismiss();
12329            app.waitDialog = null;
12330        }
12331
12332        app.crashing = false;
12333        app.notResponding = false;
12334
12335        app.resetPackageList(mProcessStats);
12336        app.unlinkDeathRecipient();
12337        app.makeInactive(mProcessStats);
12338        app.forcingToForeground = null;
12339        app.foregroundServices = false;
12340        app.foregroundActivities = false;
12341        app.hasShownUi = false;
12342        app.hasAboveClient = false;
12343
12344        mServices.killServicesLocked(app, allowRestart);
12345
12346        boolean restart = false;
12347
12348        // Remove published content providers.
12349        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12350            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12351            final boolean always = app.bad || !allowRestart;
12352            if (removeDyingProviderLocked(app, cpr, always) || always) {
12353                // We left the provider in the launching list, need to
12354                // restart it.
12355                restart = true;
12356            }
12357
12358            cpr.provider = null;
12359            cpr.proc = null;
12360        }
12361        app.pubProviders.clear();
12362
12363        // Take care of any launching providers waiting for this process.
12364        if (checkAppInLaunchingProvidersLocked(app, false)) {
12365            restart = true;
12366        }
12367
12368        // Unregister from connected content providers.
12369        if (!app.conProviders.isEmpty()) {
12370            for (int i=0; i<app.conProviders.size(); i++) {
12371                ContentProviderConnection conn = app.conProviders.get(i);
12372                conn.provider.connections.remove(conn);
12373            }
12374            app.conProviders.clear();
12375        }
12376
12377        // At this point there may be remaining entries in mLaunchingProviders
12378        // where we were the only one waiting, so they are no longer of use.
12379        // Look for these and clean up if found.
12380        // XXX Commented out for now.  Trying to figure out a way to reproduce
12381        // the actual situation to identify what is actually going on.
12382        if (false) {
12383            for (int i=0; i<mLaunchingProviders.size(); i++) {
12384                ContentProviderRecord cpr = (ContentProviderRecord)
12385                        mLaunchingProviders.get(i);
12386                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12387                    synchronized (cpr) {
12388                        cpr.launchingApp = null;
12389                        cpr.notifyAll();
12390                    }
12391                }
12392            }
12393        }
12394
12395        skipCurrentReceiverLocked(app);
12396
12397        // Unregister any receivers.
12398        for (int i=app.receivers.size()-1; i>=0; i--) {
12399            removeReceiverLocked(app.receivers.valueAt(i));
12400        }
12401        app.receivers.clear();
12402
12403        // If the app is undergoing backup, tell the backup manager about it
12404        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12405            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12406                    + mBackupTarget.appInfo + " died during backup");
12407            try {
12408                IBackupManager bm = IBackupManager.Stub.asInterface(
12409                        ServiceManager.getService(Context.BACKUP_SERVICE));
12410                bm.agentDisconnected(app.info.packageName);
12411            } catch (RemoteException e) {
12412                // can't happen; backup manager is local
12413            }
12414        }
12415
12416        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12417            ProcessChangeItem item = mPendingProcessChanges.get(i);
12418            if (item.pid == app.pid) {
12419                mPendingProcessChanges.remove(i);
12420                mAvailProcessChanges.add(item);
12421            }
12422        }
12423        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12424
12425        // If the caller is restarting this app, then leave it in its
12426        // current lists and let the caller take care of it.
12427        if (restarting) {
12428            return;
12429        }
12430
12431        if (!app.persistent || app.isolated) {
12432            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12433                    "Removing non-persistent process during cleanup: " + app);
12434            mProcessNames.remove(app.processName, app.uid);
12435            mIsolatedProcesses.remove(app.uid);
12436            if (mHeavyWeightProcess == app) {
12437                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12438                        mHeavyWeightProcess.userId, 0));
12439                mHeavyWeightProcess = null;
12440            }
12441        } else if (!app.removed) {
12442            // This app is persistent, so we need to keep its record around.
12443            // If it is not already on the pending app list, add it there
12444            // and start a new process for it.
12445            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12446                mPersistentStartingProcesses.add(app);
12447                restart = true;
12448            }
12449        }
12450        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12451                "Clean-up removing on hold: " + app);
12452        mProcessesOnHold.remove(app);
12453
12454        if (app == mHomeProcess) {
12455            mHomeProcess = null;
12456        }
12457        if (app == mPreviousProcess) {
12458            mPreviousProcess = null;
12459        }
12460
12461        if (restart && !app.isolated) {
12462            // We have components that still need to be running in the
12463            // process, so re-launch it.
12464            mProcessNames.put(app.processName, app.uid, app);
12465            startProcessLocked(app, "restart", app.processName);
12466        } else if (app.pid > 0 && app.pid != MY_PID) {
12467            // Goodbye!
12468            boolean removed;
12469            synchronized (mPidsSelfLocked) {
12470                mPidsSelfLocked.remove(app.pid);
12471                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12472            }
12473            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISHED,
12474                    app.processName, app.info.uid);
12475            if (app.isolated) {
12476                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12477            }
12478            app.setPid(0);
12479        }
12480    }
12481
12482    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12483        // Look through the content providers we are waiting to have launched,
12484        // and if any run in this process then either schedule a restart of
12485        // the process or kill the client waiting for it if this process has
12486        // gone bad.
12487        int NL = mLaunchingProviders.size();
12488        boolean restart = false;
12489        for (int i=0; i<NL; i++) {
12490            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12491            if (cpr.launchingApp == app) {
12492                if (!alwaysBad && !app.bad) {
12493                    restart = true;
12494                } else {
12495                    removeDyingProviderLocked(app, cpr, true);
12496                    // cpr should have been removed from mLaunchingProviders
12497                    NL = mLaunchingProviders.size();
12498                    i--;
12499                }
12500            }
12501        }
12502        return restart;
12503    }
12504
12505    // =========================================================
12506    // SERVICES
12507    // =========================================================
12508
12509    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12510            int flags) {
12511        enforceNotIsolatedCaller("getServices");
12512        synchronized (this) {
12513            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12514        }
12515    }
12516
12517    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12518        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12519        synchronized (this) {
12520            return mServices.getRunningServiceControlPanelLocked(name);
12521        }
12522    }
12523
12524    public ComponentName startService(IApplicationThread caller, Intent service,
12525            String resolvedType, int userId) {
12526        enforceNotIsolatedCaller("startService");
12527        // Refuse possible leaked file descriptors
12528        if (service != null && service.hasFileDescriptors() == true) {
12529            throw new IllegalArgumentException("File descriptors passed in Intent");
12530        }
12531
12532        if (DEBUG_SERVICE)
12533            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12534        synchronized(this) {
12535            final int callingPid = Binder.getCallingPid();
12536            final int callingUid = Binder.getCallingUid();
12537            final long origId = Binder.clearCallingIdentity();
12538            ComponentName res = mServices.startServiceLocked(caller, service,
12539                    resolvedType, callingPid, callingUid, userId);
12540            Binder.restoreCallingIdentity(origId);
12541            return res;
12542        }
12543    }
12544
12545    ComponentName startServiceInPackage(int uid,
12546            Intent service, String resolvedType, int userId) {
12547        synchronized(this) {
12548            if (DEBUG_SERVICE)
12549                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12550            final long origId = Binder.clearCallingIdentity();
12551            ComponentName res = mServices.startServiceLocked(null, service,
12552                    resolvedType, -1, uid, userId);
12553            Binder.restoreCallingIdentity(origId);
12554            return res;
12555        }
12556    }
12557
12558    public int stopService(IApplicationThread caller, Intent service,
12559            String resolvedType, int userId) {
12560        enforceNotIsolatedCaller("stopService");
12561        // Refuse possible leaked file descriptors
12562        if (service != null && service.hasFileDescriptors() == true) {
12563            throw new IllegalArgumentException("File descriptors passed in Intent");
12564        }
12565
12566        synchronized(this) {
12567            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12568        }
12569    }
12570
12571    public IBinder peekService(Intent service, String resolvedType) {
12572        enforceNotIsolatedCaller("peekService");
12573        // Refuse possible leaked file descriptors
12574        if (service != null && service.hasFileDescriptors() == true) {
12575            throw new IllegalArgumentException("File descriptors passed in Intent");
12576        }
12577        synchronized(this) {
12578            return mServices.peekServiceLocked(service, resolvedType);
12579        }
12580    }
12581
12582    public boolean stopServiceToken(ComponentName className, IBinder token,
12583            int startId) {
12584        synchronized(this) {
12585            return mServices.stopServiceTokenLocked(className, token, startId);
12586        }
12587    }
12588
12589    public void setServiceForeground(ComponentName className, IBinder token,
12590            int id, Notification notification, boolean removeNotification) {
12591        synchronized(this) {
12592            mServices.setServiceForegroundLocked(className, token, id, notification,
12593                    removeNotification);
12594        }
12595    }
12596
12597    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12598            boolean requireFull, String name, String callerPackage) {
12599        final int callingUserId = UserHandle.getUserId(callingUid);
12600        if (callingUserId != userId) {
12601            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12602                if ((requireFull || checkComponentPermission(
12603                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12604                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12605                        && checkComponentPermission(
12606                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12607                                callingPid, callingUid, -1, true)
12608                                != PackageManager.PERMISSION_GRANTED) {
12609                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12610                        // In this case, they would like to just execute as their
12611                        // owner user instead of failing.
12612                        userId = callingUserId;
12613                    } else {
12614                        StringBuilder builder = new StringBuilder(128);
12615                        builder.append("Permission Denial: ");
12616                        builder.append(name);
12617                        if (callerPackage != null) {
12618                            builder.append(" from ");
12619                            builder.append(callerPackage);
12620                        }
12621                        builder.append(" asks to run as user ");
12622                        builder.append(userId);
12623                        builder.append(" but is calling from user ");
12624                        builder.append(UserHandle.getUserId(callingUid));
12625                        builder.append("; this requires ");
12626                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12627                        if (!requireFull) {
12628                            builder.append(" or ");
12629                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12630                        }
12631                        String msg = builder.toString();
12632                        Slog.w(TAG, msg);
12633                        throw new SecurityException(msg);
12634                    }
12635                }
12636            }
12637            if (userId == UserHandle.USER_CURRENT
12638                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12639                // Note that we may be accessing this outside of a lock...
12640                // shouldn't be a big deal, if this is being called outside
12641                // of a locked context there is intrinsically a race with
12642                // the value the caller will receive and someone else changing it.
12643                userId = mCurrentUserId;
12644            }
12645            if (!allowAll && userId < 0) {
12646                throw new IllegalArgumentException(
12647                        "Call does not support special user #" + userId);
12648            }
12649        }
12650        return userId;
12651    }
12652
12653    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12654            String className, int flags) {
12655        boolean result = false;
12656        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12657            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12658                if (ActivityManager.checkUidPermission(
12659                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12660                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12661                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12662                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12663                            + " requests FLAG_SINGLE_USER, but app does not hold "
12664                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12665                    Slog.w(TAG, msg);
12666                    throw new SecurityException(msg);
12667                }
12668                result = true;
12669            }
12670        } else if (componentProcessName == aInfo.packageName) {
12671            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12672        } else if ("system".equals(componentProcessName)) {
12673            result = true;
12674        }
12675        if (DEBUG_MU) {
12676            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12677                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12678        }
12679        return result;
12680    }
12681
12682    public int bindService(IApplicationThread caller, IBinder token,
12683            Intent service, String resolvedType,
12684            IServiceConnection connection, int flags, int userId) {
12685        enforceNotIsolatedCaller("bindService");
12686        // Refuse possible leaked file descriptors
12687        if (service != null && service.hasFileDescriptors() == true) {
12688            throw new IllegalArgumentException("File descriptors passed in Intent");
12689        }
12690
12691        synchronized(this) {
12692            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12693                    connection, flags, userId);
12694        }
12695    }
12696
12697    public boolean unbindService(IServiceConnection connection) {
12698        synchronized (this) {
12699            return mServices.unbindServiceLocked(connection);
12700        }
12701    }
12702
12703    public void publishService(IBinder token, Intent intent, IBinder service) {
12704        // Refuse possible leaked file descriptors
12705        if (intent != null && intent.hasFileDescriptors() == true) {
12706            throw new IllegalArgumentException("File descriptors passed in Intent");
12707        }
12708
12709        synchronized(this) {
12710            if (!(token instanceof ServiceRecord)) {
12711                throw new IllegalArgumentException("Invalid service token");
12712            }
12713            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12714        }
12715    }
12716
12717    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12718        // Refuse possible leaked file descriptors
12719        if (intent != null && intent.hasFileDescriptors() == true) {
12720            throw new IllegalArgumentException("File descriptors passed in Intent");
12721        }
12722
12723        synchronized(this) {
12724            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12725        }
12726    }
12727
12728    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12729        synchronized(this) {
12730            if (!(token instanceof ServiceRecord)) {
12731                throw new IllegalArgumentException("Invalid service token");
12732            }
12733            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12734        }
12735    }
12736
12737    // =========================================================
12738    // BACKUP AND RESTORE
12739    // =========================================================
12740
12741    // Cause the target app to be launched if necessary and its backup agent
12742    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12743    // activity manager to announce its creation.
12744    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12745        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12746        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12747
12748        synchronized(this) {
12749            // !!! TODO: currently no check here that we're already bound
12750            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12751            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12752            synchronized (stats) {
12753                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12754            }
12755
12756            // Backup agent is now in use, its package can't be stopped.
12757            try {
12758                AppGlobals.getPackageManager().setPackageStoppedState(
12759                        app.packageName, false, UserHandle.getUserId(app.uid));
12760            } catch (RemoteException e) {
12761            } catch (IllegalArgumentException e) {
12762                Slog.w(TAG, "Failed trying to unstop package "
12763                        + app.packageName + ": " + e);
12764            }
12765
12766            BackupRecord r = new BackupRecord(ss, app, backupMode);
12767            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12768                    ? new ComponentName(app.packageName, app.backupAgentName)
12769                    : new ComponentName("android", "FullBackupAgent");
12770            // startProcessLocked() returns existing proc's record if it's already running
12771            ProcessRecord proc = startProcessLocked(app.processName, app,
12772                    false, 0, "backup", hostingName, false, false, false);
12773            if (proc == null) {
12774                Slog.e(TAG, "Unable to start backup agent process " + r);
12775                return false;
12776            }
12777
12778            r.app = proc;
12779            mBackupTarget = r;
12780            mBackupAppName = app.packageName;
12781
12782            // Try not to kill the process during backup
12783            updateOomAdjLocked(proc);
12784
12785            // If the process is already attached, schedule the creation of the backup agent now.
12786            // If it is not yet live, this will be done when it attaches to the framework.
12787            if (proc.thread != null) {
12788                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12789                try {
12790                    proc.thread.scheduleCreateBackupAgent(app,
12791                            compatibilityInfoForPackageLocked(app), backupMode);
12792                } catch (RemoteException e) {
12793                    // Will time out on the backup manager side
12794                }
12795            } else {
12796                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12797            }
12798            // Invariants: at this point, the target app process exists and the application
12799            // is either already running or in the process of coming up.  mBackupTarget and
12800            // mBackupAppName describe the app, so that when it binds back to the AM we
12801            // know that it's scheduled for a backup-agent operation.
12802        }
12803
12804        return true;
12805    }
12806
12807    @Override
12808    public void clearPendingBackup() {
12809        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12810        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12811
12812        synchronized (this) {
12813            mBackupTarget = null;
12814            mBackupAppName = null;
12815        }
12816    }
12817
12818    // A backup agent has just come up
12819    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12820        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12821                + " = " + agent);
12822
12823        synchronized(this) {
12824            if (!agentPackageName.equals(mBackupAppName)) {
12825                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12826                return;
12827            }
12828        }
12829
12830        long oldIdent = Binder.clearCallingIdentity();
12831        try {
12832            IBackupManager bm = IBackupManager.Stub.asInterface(
12833                    ServiceManager.getService(Context.BACKUP_SERVICE));
12834            bm.agentConnected(agentPackageName, agent);
12835        } catch (RemoteException e) {
12836            // can't happen; the backup manager service is local
12837        } catch (Exception e) {
12838            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12839            e.printStackTrace();
12840        } finally {
12841            Binder.restoreCallingIdentity(oldIdent);
12842        }
12843    }
12844
12845    // done with this agent
12846    public void unbindBackupAgent(ApplicationInfo appInfo) {
12847        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12848        if (appInfo == null) {
12849            Slog.w(TAG, "unbind backup agent for null app");
12850            return;
12851        }
12852
12853        synchronized(this) {
12854            try {
12855                if (mBackupAppName == null) {
12856                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12857                    return;
12858                }
12859
12860                if (!mBackupAppName.equals(appInfo.packageName)) {
12861                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12862                    return;
12863                }
12864
12865                // Not backing this app up any more; reset its OOM adjustment
12866                final ProcessRecord proc = mBackupTarget.app;
12867                updateOomAdjLocked(proc);
12868
12869                // If the app crashed during backup, 'thread' will be null here
12870                if (proc.thread != null) {
12871                    try {
12872                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12873                                compatibilityInfoForPackageLocked(appInfo));
12874                    } catch (Exception e) {
12875                        Slog.e(TAG, "Exception when unbinding backup agent:");
12876                        e.printStackTrace();
12877                    }
12878                }
12879            } finally {
12880                mBackupTarget = null;
12881                mBackupAppName = null;
12882            }
12883        }
12884    }
12885    // =========================================================
12886    // BROADCASTS
12887    // =========================================================
12888
12889    private final List getStickiesLocked(String action, IntentFilter filter,
12890            List cur, int userId) {
12891        final ContentResolver resolver = mContext.getContentResolver();
12892        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12893        if (stickies == null) {
12894            return cur;
12895        }
12896        final ArrayList<Intent> list = stickies.get(action);
12897        if (list == null) {
12898            return cur;
12899        }
12900        int N = list.size();
12901        for (int i=0; i<N; i++) {
12902            Intent intent = list.get(i);
12903            if (filter.match(resolver, intent, true, TAG) >= 0) {
12904                if (cur == null) {
12905                    cur = new ArrayList<Intent>();
12906                }
12907                cur.add(intent);
12908            }
12909        }
12910        return cur;
12911    }
12912
12913    boolean isPendingBroadcastProcessLocked(int pid) {
12914        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12915                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12916    }
12917
12918    void skipPendingBroadcastLocked(int pid) {
12919            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12920            for (BroadcastQueue queue : mBroadcastQueues) {
12921                queue.skipPendingBroadcastLocked(pid);
12922            }
12923    }
12924
12925    // The app just attached; send any pending broadcasts that it should receive
12926    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12927        boolean didSomething = false;
12928        for (BroadcastQueue queue : mBroadcastQueues) {
12929            didSomething |= queue.sendPendingBroadcastsLocked(app);
12930        }
12931        return didSomething;
12932    }
12933
12934    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12935            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12936        enforceNotIsolatedCaller("registerReceiver");
12937        int callingUid;
12938        int callingPid;
12939        synchronized(this) {
12940            ProcessRecord callerApp = null;
12941            if (caller != null) {
12942                callerApp = getRecordForAppLocked(caller);
12943                if (callerApp == null) {
12944                    throw new SecurityException(
12945                            "Unable to find app for caller " + caller
12946                            + " (pid=" + Binder.getCallingPid()
12947                            + ") when registering receiver " + receiver);
12948                }
12949                if (callerApp.info.uid != Process.SYSTEM_UID &&
12950                        !callerApp.pkgList.containsKey(callerPackage) &&
12951                        !"android".equals(callerPackage)) {
12952                    throw new SecurityException("Given caller package " + callerPackage
12953                            + " is not running in process " + callerApp);
12954                }
12955                callingUid = callerApp.info.uid;
12956                callingPid = callerApp.pid;
12957            } else {
12958                callerPackage = null;
12959                callingUid = Binder.getCallingUid();
12960                callingPid = Binder.getCallingPid();
12961            }
12962
12963            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12964                    true, true, "registerReceiver", callerPackage);
12965
12966            List allSticky = null;
12967
12968            // Look for any matching sticky broadcasts...
12969            Iterator actions = filter.actionsIterator();
12970            if (actions != null) {
12971                while (actions.hasNext()) {
12972                    String action = (String)actions.next();
12973                    allSticky = getStickiesLocked(action, filter, allSticky,
12974                            UserHandle.USER_ALL);
12975                    allSticky = getStickiesLocked(action, filter, allSticky,
12976                            UserHandle.getUserId(callingUid));
12977                }
12978            } else {
12979                allSticky = getStickiesLocked(null, filter, allSticky,
12980                        UserHandle.USER_ALL);
12981                allSticky = getStickiesLocked(null, filter, allSticky,
12982                        UserHandle.getUserId(callingUid));
12983            }
12984
12985            // The first sticky in the list is returned directly back to
12986            // the client.
12987            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12988
12989            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12990                    + ": " + sticky);
12991
12992            if (receiver == null) {
12993                return sticky;
12994            }
12995
12996            ReceiverList rl
12997                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12998            if (rl == null) {
12999                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13000                        userId, receiver);
13001                if (rl.app != null) {
13002                    rl.app.receivers.add(rl);
13003                } else {
13004                    try {
13005                        receiver.asBinder().linkToDeath(rl, 0);
13006                    } catch (RemoteException e) {
13007                        return sticky;
13008                    }
13009                    rl.linkedToDeath = true;
13010                }
13011                mRegisteredReceivers.put(receiver.asBinder(), rl);
13012            } else if (rl.uid != callingUid) {
13013                throw new IllegalArgumentException(
13014                        "Receiver requested to register for uid " + callingUid
13015                        + " was previously registered for uid " + rl.uid);
13016            } else if (rl.pid != callingPid) {
13017                throw new IllegalArgumentException(
13018                        "Receiver requested to register for pid " + callingPid
13019                        + " was previously registered for pid " + rl.pid);
13020            } else if (rl.userId != userId) {
13021                throw new IllegalArgumentException(
13022                        "Receiver requested to register for user " + userId
13023                        + " was previously registered for user " + rl.userId);
13024            }
13025            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13026                    permission, callingUid, userId);
13027            rl.add(bf);
13028            if (!bf.debugCheck()) {
13029                Slog.w(TAG, "==> For Dynamic broadast");
13030            }
13031            mReceiverResolver.addFilter(bf);
13032
13033            // Enqueue broadcasts for all existing stickies that match
13034            // this filter.
13035            if (allSticky != null) {
13036                ArrayList receivers = new ArrayList();
13037                receivers.add(bf);
13038
13039                int N = allSticky.size();
13040                for (int i=0; i<N; i++) {
13041                    Intent intent = (Intent)allSticky.get(i);
13042                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13043                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13044                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13045                            null, null, false, true, true, -1);
13046                    queue.enqueueParallelBroadcastLocked(r);
13047                    queue.scheduleBroadcastsLocked();
13048                }
13049            }
13050
13051            return sticky;
13052        }
13053    }
13054
13055    public void unregisterReceiver(IIntentReceiver receiver) {
13056        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13057
13058        final long origId = Binder.clearCallingIdentity();
13059        try {
13060            boolean doTrim = false;
13061
13062            synchronized(this) {
13063                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13064                if (rl != null) {
13065                    if (rl.curBroadcast != null) {
13066                        BroadcastRecord r = rl.curBroadcast;
13067                        final boolean doNext = finishReceiverLocked(
13068                                receiver.asBinder(), r.resultCode, r.resultData,
13069                                r.resultExtras, r.resultAbort);
13070                        if (doNext) {
13071                            doTrim = true;
13072                            r.queue.processNextBroadcast(false);
13073                        }
13074                    }
13075
13076                    if (rl.app != null) {
13077                        rl.app.receivers.remove(rl);
13078                    }
13079                    removeReceiverLocked(rl);
13080                    if (rl.linkedToDeath) {
13081                        rl.linkedToDeath = false;
13082                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13083                    }
13084                }
13085            }
13086
13087            // If we actually concluded any broadcasts, we might now be able
13088            // to trim the recipients' apps from our working set
13089            if (doTrim) {
13090                trimApplications();
13091                return;
13092            }
13093
13094        } finally {
13095            Binder.restoreCallingIdentity(origId);
13096        }
13097    }
13098
13099    void removeReceiverLocked(ReceiverList rl) {
13100        mRegisteredReceivers.remove(rl.receiver.asBinder());
13101        int N = rl.size();
13102        for (int i=0; i<N; i++) {
13103            mReceiverResolver.removeFilter(rl.get(i));
13104        }
13105    }
13106
13107    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13108        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13109            ProcessRecord r = mLruProcesses.get(i);
13110            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13111                try {
13112                    r.thread.dispatchPackageBroadcast(cmd, packages);
13113                } catch (RemoteException ex) {
13114                }
13115            }
13116        }
13117    }
13118
13119    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13120            int[] users) {
13121        List<ResolveInfo> receivers = null;
13122        try {
13123            HashSet<ComponentName> singleUserReceivers = null;
13124            boolean scannedFirstReceivers = false;
13125            for (int user : users) {
13126                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13127                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13128                if (user != 0 && newReceivers != null) {
13129                    // If this is not the primary user, we need to check for
13130                    // any receivers that should be filtered out.
13131                    for (int i=0; i<newReceivers.size(); i++) {
13132                        ResolveInfo ri = newReceivers.get(i);
13133                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13134                            newReceivers.remove(i);
13135                            i--;
13136                        }
13137                    }
13138                }
13139                if (newReceivers != null && newReceivers.size() == 0) {
13140                    newReceivers = null;
13141                }
13142                if (receivers == null) {
13143                    receivers = newReceivers;
13144                } else if (newReceivers != null) {
13145                    // We need to concatenate the additional receivers
13146                    // found with what we have do far.  This would be easy,
13147                    // but we also need to de-dup any receivers that are
13148                    // singleUser.
13149                    if (!scannedFirstReceivers) {
13150                        // Collect any single user receivers we had already retrieved.
13151                        scannedFirstReceivers = true;
13152                        for (int i=0; i<receivers.size(); i++) {
13153                            ResolveInfo ri = receivers.get(i);
13154                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13155                                ComponentName cn = new ComponentName(
13156                                        ri.activityInfo.packageName, ri.activityInfo.name);
13157                                if (singleUserReceivers == null) {
13158                                    singleUserReceivers = new HashSet<ComponentName>();
13159                                }
13160                                singleUserReceivers.add(cn);
13161                            }
13162                        }
13163                    }
13164                    // Add the new results to the existing results, tracking
13165                    // and de-dupping single user receivers.
13166                    for (int i=0; i<newReceivers.size(); i++) {
13167                        ResolveInfo ri = newReceivers.get(i);
13168                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13169                            ComponentName cn = new ComponentName(
13170                                    ri.activityInfo.packageName, ri.activityInfo.name);
13171                            if (singleUserReceivers == null) {
13172                                singleUserReceivers = new HashSet<ComponentName>();
13173                            }
13174                            if (!singleUserReceivers.contains(cn)) {
13175                                singleUserReceivers.add(cn);
13176                                receivers.add(ri);
13177                            }
13178                        } else {
13179                            receivers.add(ri);
13180                        }
13181                    }
13182                }
13183            }
13184        } catch (RemoteException ex) {
13185            // pm is in same process, this will never happen.
13186        }
13187        return receivers;
13188    }
13189
13190    private final int broadcastIntentLocked(ProcessRecord callerApp,
13191            String callerPackage, Intent intent, String resolvedType,
13192            IIntentReceiver resultTo, int resultCode, String resultData,
13193            Bundle map, String requiredPermission, int appOp,
13194            boolean ordered, boolean sticky, int callingPid, int callingUid,
13195            int userId) {
13196        intent = new Intent(intent);
13197
13198        // By default broadcasts do not go to stopped apps.
13199        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13200
13201        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13202            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13203            + " ordered=" + ordered + " userid=" + userId);
13204        if ((resultTo != null) && !ordered) {
13205            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13206        }
13207
13208        userId = handleIncomingUser(callingPid, callingUid, userId,
13209                true, false, "broadcast", callerPackage);
13210
13211        // Make sure that the user who is receiving this broadcast is started.
13212        // If not, we will just skip it.
13213        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13214            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13215                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13216                Slog.w(TAG, "Skipping broadcast of " + intent
13217                        + ": user " + userId + " is stopped");
13218                return ActivityManager.BROADCAST_SUCCESS;
13219            }
13220        }
13221
13222        /*
13223         * Prevent non-system code (defined here to be non-persistent
13224         * processes) from sending protected broadcasts.
13225         */
13226        int callingAppId = UserHandle.getAppId(callingUid);
13227        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13228            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13229            callingUid == 0) {
13230            // Always okay.
13231        } else if (callerApp == null || !callerApp.persistent) {
13232            try {
13233                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13234                        intent.getAction())) {
13235                    String msg = "Permission Denial: not allowed to send broadcast "
13236                            + intent.getAction() + " from pid="
13237                            + callingPid + ", uid=" + callingUid;
13238                    Slog.w(TAG, msg);
13239                    throw new SecurityException(msg);
13240                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13241                    // Special case for compatibility: we don't want apps to send this,
13242                    // but historically it has not been protected and apps may be using it
13243                    // to poke their own app widget.  So, instead of making it protected,
13244                    // just limit it to the caller.
13245                    if (callerApp == null) {
13246                        String msg = "Permission Denial: not allowed to send broadcast "
13247                                + intent.getAction() + " from unknown caller.";
13248                        Slog.w(TAG, msg);
13249                        throw new SecurityException(msg);
13250                    } else if (intent.getComponent() != null) {
13251                        // They are good enough to send to an explicit component...  verify
13252                        // it is being sent to the calling app.
13253                        if (!intent.getComponent().getPackageName().equals(
13254                                callerApp.info.packageName)) {
13255                            String msg = "Permission Denial: not allowed to send broadcast "
13256                                    + intent.getAction() + " to "
13257                                    + intent.getComponent().getPackageName() + " from "
13258                                    + callerApp.info.packageName;
13259                            Slog.w(TAG, msg);
13260                            throw new SecurityException(msg);
13261                        }
13262                    } else {
13263                        // Limit broadcast to their own package.
13264                        intent.setPackage(callerApp.info.packageName);
13265                    }
13266                }
13267            } catch (RemoteException e) {
13268                Slog.w(TAG, "Remote exception", e);
13269                return ActivityManager.BROADCAST_SUCCESS;
13270            }
13271        }
13272
13273        // Handle special intents: if this broadcast is from the package
13274        // manager about a package being removed, we need to remove all of
13275        // its activities from the history stack.
13276        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13277                intent.getAction());
13278        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13279                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13280                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13281                || uidRemoved) {
13282            if (checkComponentPermission(
13283                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13284                    callingPid, callingUid, -1, true)
13285                    == PackageManager.PERMISSION_GRANTED) {
13286                if (uidRemoved) {
13287                    final Bundle intentExtras = intent.getExtras();
13288                    final int uid = intentExtras != null
13289                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13290                    if (uid >= 0) {
13291                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13292                        synchronized (bs) {
13293                            bs.removeUidStatsLocked(uid);
13294                        }
13295                        mAppOpsService.uidRemoved(uid);
13296                    }
13297                } else {
13298                    // If resources are unavailable just force stop all
13299                    // those packages and flush the attribute cache as well.
13300                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13301                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13302                        if (list != null && (list.length > 0)) {
13303                            for (String pkg : list) {
13304                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13305                                        "storage unmount");
13306                            }
13307                            sendPackageBroadcastLocked(
13308                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13309                        }
13310                    } else {
13311                        Uri data = intent.getData();
13312                        String ssp;
13313                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13314                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13315                                    intent.getAction());
13316                            boolean fullUninstall = removed &&
13317                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13318                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13319                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13320                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13321                                        false, fullUninstall, userId,
13322                                        removed ? "pkg removed" : "pkg changed");
13323                            }
13324                            if (removed) {
13325                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13326                                        new String[] {ssp}, userId);
13327                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13328                                    mAppOpsService.packageRemoved(
13329                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13330
13331                                    // Remove all permissions granted from/to this package
13332                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13333                                }
13334                            }
13335                        }
13336                    }
13337                }
13338            } else {
13339                String msg = "Permission Denial: " + intent.getAction()
13340                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13341                        + ", uid=" + callingUid + ")"
13342                        + " requires "
13343                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13344                Slog.w(TAG, msg);
13345                throw new SecurityException(msg);
13346            }
13347
13348        // Special case for adding a package: by default turn on compatibility
13349        // mode.
13350        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13351            Uri data = intent.getData();
13352            String ssp;
13353            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13354                mCompatModePackages.handlePackageAddedLocked(ssp,
13355                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13356            }
13357        }
13358
13359        /*
13360         * If this is the time zone changed action, queue up a message that will reset the timezone
13361         * of all currently running processes. This message will get queued up before the broadcast
13362         * happens.
13363         */
13364        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13365            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13366        }
13367
13368        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13369            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13370        }
13371
13372        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13373            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13374            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13375        }
13376
13377        // Add to the sticky list if requested.
13378        if (sticky) {
13379            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13380                    callingPid, callingUid)
13381                    != PackageManager.PERMISSION_GRANTED) {
13382                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13383                        + callingPid + ", uid=" + callingUid
13384                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13385                Slog.w(TAG, msg);
13386                throw new SecurityException(msg);
13387            }
13388            if (requiredPermission != null) {
13389                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13390                        + " and enforce permission " + requiredPermission);
13391                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13392            }
13393            if (intent.getComponent() != null) {
13394                throw new SecurityException(
13395                        "Sticky broadcasts can't target a specific component");
13396            }
13397            // We use userId directly here, since the "all" target is maintained
13398            // as a separate set of sticky broadcasts.
13399            if (userId != UserHandle.USER_ALL) {
13400                // But first, if this is not a broadcast to all users, then
13401                // make sure it doesn't conflict with an existing broadcast to
13402                // all users.
13403                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13404                        UserHandle.USER_ALL);
13405                if (stickies != null) {
13406                    ArrayList<Intent> list = stickies.get(intent.getAction());
13407                    if (list != null) {
13408                        int N = list.size();
13409                        int i;
13410                        for (i=0; i<N; i++) {
13411                            if (intent.filterEquals(list.get(i))) {
13412                                throw new IllegalArgumentException(
13413                                        "Sticky broadcast " + intent + " for user "
13414                                        + userId + " conflicts with existing global broadcast");
13415                            }
13416                        }
13417                    }
13418                }
13419            }
13420            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13421            if (stickies == null) {
13422                stickies = new ArrayMap<String, ArrayList<Intent>>();
13423                mStickyBroadcasts.put(userId, stickies);
13424            }
13425            ArrayList<Intent> list = stickies.get(intent.getAction());
13426            if (list == null) {
13427                list = new ArrayList<Intent>();
13428                stickies.put(intent.getAction(), list);
13429            }
13430            int N = list.size();
13431            int i;
13432            for (i=0; i<N; i++) {
13433                if (intent.filterEquals(list.get(i))) {
13434                    // This sticky already exists, replace it.
13435                    list.set(i, new Intent(intent));
13436                    break;
13437                }
13438            }
13439            if (i >= N) {
13440                list.add(new Intent(intent));
13441            }
13442        }
13443
13444        int[] users;
13445        if (userId == UserHandle.USER_ALL) {
13446            // Caller wants broadcast to go to all started users.
13447            users = mStartedUserArray;
13448        } else {
13449            // Caller wants broadcast to go to one specific user.
13450            users = new int[] {userId};
13451        }
13452
13453        // Figure out who all will receive this broadcast.
13454        List receivers = null;
13455        List<BroadcastFilter> registeredReceivers = null;
13456        // Need to resolve the intent to interested receivers...
13457        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13458                 == 0) {
13459            receivers = collectReceiverComponents(intent, resolvedType, users);
13460        }
13461        if (intent.getComponent() == null) {
13462            registeredReceivers = mReceiverResolver.queryIntent(intent,
13463                    resolvedType, false, userId);
13464        }
13465
13466        final boolean replacePending =
13467                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13468
13469        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13470                + " replacePending=" + replacePending);
13471
13472        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13473        if (!ordered && NR > 0) {
13474            // If we are not serializing this broadcast, then send the
13475            // registered receivers separately so they don't wait for the
13476            // components to be launched.
13477            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13478            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13479                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13480                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13481                    ordered, sticky, false, userId);
13482            if (DEBUG_BROADCAST) Slog.v(
13483                    TAG, "Enqueueing parallel broadcast " + r);
13484            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13485            if (!replaced) {
13486                queue.enqueueParallelBroadcastLocked(r);
13487                queue.scheduleBroadcastsLocked();
13488            }
13489            registeredReceivers = null;
13490            NR = 0;
13491        }
13492
13493        // Merge into one list.
13494        int ir = 0;
13495        if (receivers != null) {
13496            // A special case for PACKAGE_ADDED: do not allow the package
13497            // being added to see this broadcast.  This prevents them from
13498            // using this as a back door to get run as soon as they are
13499            // installed.  Maybe in the future we want to have a special install
13500            // broadcast or such for apps, but we'd like to deliberately make
13501            // this decision.
13502            String skipPackages[] = null;
13503            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13504                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13505                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13506                Uri data = intent.getData();
13507                if (data != null) {
13508                    String pkgName = data.getSchemeSpecificPart();
13509                    if (pkgName != null) {
13510                        skipPackages = new String[] { pkgName };
13511                    }
13512                }
13513            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13514                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13515            }
13516            if (skipPackages != null && (skipPackages.length > 0)) {
13517                for (String skipPackage : skipPackages) {
13518                    if (skipPackage != null) {
13519                        int NT = receivers.size();
13520                        for (int it=0; it<NT; it++) {
13521                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13522                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13523                                receivers.remove(it);
13524                                it--;
13525                                NT--;
13526                            }
13527                        }
13528                    }
13529                }
13530            }
13531
13532            int NT = receivers != null ? receivers.size() : 0;
13533            int it = 0;
13534            ResolveInfo curt = null;
13535            BroadcastFilter curr = null;
13536            while (it < NT && ir < NR) {
13537                if (curt == null) {
13538                    curt = (ResolveInfo)receivers.get(it);
13539                }
13540                if (curr == null) {
13541                    curr = registeredReceivers.get(ir);
13542                }
13543                if (curr.getPriority() >= curt.priority) {
13544                    // Insert this broadcast record into the final list.
13545                    receivers.add(it, curr);
13546                    ir++;
13547                    curr = null;
13548                    it++;
13549                    NT++;
13550                } else {
13551                    // Skip to the next ResolveInfo in the final list.
13552                    it++;
13553                    curt = null;
13554                }
13555            }
13556        }
13557        while (ir < NR) {
13558            if (receivers == null) {
13559                receivers = new ArrayList();
13560            }
13561            receivers.add(registeredReceivers.get(ir));
13562            ir++;
13563        }
13564
13565        if ((receivers != null && receivers.size() > 0)
13566                || resultTo != null) {
13567            BroadcastQueue queue = broadcastQueueForIntent(intent);
13568            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13569                    callerPackage, callingPid, callingUid, resolvedType,
13570                    requiredPermission, appOp, receivers, resultTo, resultCode,
13571                    resultData, map, ordered, sticky, false, userId);
13572            if (DEBUG_BROADCAST) Slog.v(
13573                    TAG, "Enqueueing ordered broadcast " + r
13574                    + ": prev had " + queue.mOrderedBroadcasts.size());
13575            if (DEBUG_BROADCAST) {
13576                int seq = r.intent.getIntExtra("seq", -1);
13577                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13578            }
13579            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13580            if (!replaced) {
13581                queue.enqueueOrderedBroadcastLocked(r);
13582                queue.scheduleBroadcastsLocked();
13583            }
13584        }
13585
13586        return ActivityManager.BROADCAST_SUCCESS;
13587    }
13588
13589    final Intent verifyBroadcastLocked(Intent intent) {
13590        // Refuse possible leaked file descriptors
13591        if (intent != null && intent.hasFileDescriptors() == true) {
13592            throw new IllegalArgumentException("File descriptors passed in Intent");
13593        }
13594
13595        int flags = intent.getFlags();
13596
13597        if (!mProcessesReady) {
13598            // if the caller really truly claims to know what they're doing, go
13599            // ahead and allow the broadcast without launching any receivers
13600            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13601                intent = new Intent(intent);
13602                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13603            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13604                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13605                        + " before boot completion");
13606                throw new IllegalStateException("Cannot broadcast before boot completed");
13607            }
13608        }
13609
13610        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13611            throw new IllegalArgumentException(
13612                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13613        }
13614
13615        return intent;
13616    }
13617
13618    public final int broadcastIntent(IApplicationThread caller,
13619            Intent intent, String resolvedType, IIntentReceiver resultTo,
13620            int resultCode, String resultData, Bundle map,
13621            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13622        enforceNotIsolatedCaller("broadcastIntent");
13623        synchronized(this) {
13624            intent = verifyBroadcastLocked(intent);
13625
13626            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13627            final int callingPid = Binder.getCallingPid();
13628            final int callingUid = Binder.getCallingUid();
13629            final long origId = Binder.clearCallingIdentity();
13630            int res = broadcastIntentLocked(callerApp,
13631                    callerApp != null ? callerApp.info.packageName : null,
13632                    intent, resolvedType, resultTo,
13633                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13634                    callingPid, callingUid, userId);
13635            Binder.restoreCallingIdentity(origId);
13636            return res;
13637        }
13638    }
13639
13640    int broadcastIntentInPackage(String packageName, int uid,
13641            Intent intent, String resolvedType, IIntentReceiver resultTo,
13642            int resultCode, String resultData, Bundle map,
13643            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13644        synchronized(this) {
13645            intent = verifyBroadcastLocked(intent);
13646
13647            final long origId = Binder.clearCallingIdentity();
13648            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13649                    resultTo, resultCode, resultData, map, requiredPermission,
13650                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13651            Binder.restoreCallingIdentity(origId);
13652            return res;
13653        }
13654    }
13655
13656    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13657        // Refuse possible leaked file descriptors
13658        if (intent != null && intent.hasFileDescriptors() == true) {
13659            throw new IllegalArgumentException("File descriptors passed in Intent");
13660        }
13661
13662        userId = handleIncomingUser(Binder.getCallingPid(),
13663                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13664
13665        synchronized(this) {
13666            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13667                    != PackageManager.PERMISSION_GRANTED) {
13668                String msg = "Permission Denial: unbroadcastIntent() from pid="
13669                        + Binder.getCallingPid()
13670                        + ", uid=" + Binder.getCallingUid()
13671                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13672                Slog.w(TAG, msg);
13673                throw new SecurityException(msg);
13674            }
13675            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13676            if (stickies != null) {
13677                ArrayList<Intent> list = stickies.get(intent.getAction());
13678                if (list != null) {
13679                    int N = list.size();
13680                    int i;
13681                    for (i=0; i<N; i++) {
13682                        if (intent.filterEquals(list.get(i))) {
13683                            list.remove(i);
13684                            break;
13685                        }
13686                    }
13687                    if (list.size() <= 0) {
13688                        stickies.remove(intent.getAction());
13689                    }
13690                }
13691                if (stickies.size() <= 0) {
13692                    mStickyBroadcasts.remove(userId);
13693                }
13694            }
13695        }
13696    }
13697
13698    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13699            String resultData, Bundle resultExtras, boolean resultAbort) {
13700        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13701        if (r == null) {
13702            Slog.w(TAG, "finishReceiver called but not found on queue");
13703            return false;
13704        }
13705
13706        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13707    }
13708
13709    void backgroundServicesFinishedLocked(int userId) {
13710        for (BroadcastQueue queue : mBroadcastQueues) {
13711            queue.backgroundServicesFinishedLocked(userId);
13712        }
13713    }
13714
13715    public void finishReceiver(IBinder who, int resultCode, String resultData,
13716            Bundle resultExtras, boolean resultAbort) {
13717        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13718
13719        // Refuse possible leaked file descriptors
13720        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13721            throw new IllegalArgumentException("File descriptors passed in Bundle");
13722        }
13723
13724        final long origId = Binder.clearCallingIdentity();
13725        try {
13726            boolean doNext = false;
13727            BroadcastRecord r;
13728
13729            synchronized(this) {
13730                r = broadcastRecordForReceiverLocked(who);
13731                if (r != null) {
13732                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13733                        resultData, resultExtras, resultAbort, true);
13734                }
13735            }
13736
13737            if (doNext) {
13738                r.queue.processNextBroadcast(false);
13739            }
13740            trimApplications();
13741        } finally {
13742            Binder.restoreCallingIdentity(origId);
13743        }
13744    }
13745
13746    // =========================================================
13747    // INSTRUMENTATION
13748    // =========================================================
13749
13750    public boolean startInstrumentation(ComponentName className,
13751            String profileFile, int flags, Bundle arguments,
13752            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13753            int userId) {
13754        enforceNotIsolatedCaller("startInstrumentation");
13755        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13756                userId, false, true, "startInstrumentation", null);
13757        // Refuse possible leaked file descriptors
13758        if (arguments != null && arguments.hasFileDescriptors()) {
13759            throw new IllegalArgumentException("File descriptors passed in Bundle");
13760        }
13761
13762        synchronized(this) {
13763            InstrumentationInfo ii = null;
13764            ApplicationInfo ai = null;
13765            try {
13766                ii = mContext.getPackageManager().getInstrumentationInfo(
13767                    className, STOCK_PM_FLAGS);
13768                ai = AppGlobals.getPackageManager().getApplicationInfo(
13769                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13770            } catch (PackageManager.NameNotFoundException e) {
13771            } catch (RemoteException e) {
13772            }
13773            if (ii == null) {
13774                reportStartInstrumentationFailure(watcher, className,
13775                        "Unable to find instrumentation info for: " + className);
13776                return false;
13777            }
13778            if (ai == null) {
13779                reportStartInstrumentationFailure(watcher, className,
13780                        "Unable to find instrumentation target package: " + ii.targetPackage);
13781                return false;
13782            }
13783
13784            int match = mContext.getPackageManager().checkSignatures(
13785                    ii.targetPackage, ii.packageName);
13786            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13787                String msg = "Permission Denial: starting instrumentation "
13788                        + className + " from pid="
13789                        + Binder.getCallingPid()
13790                        + ", uid=" + Binder.getCallingPid()
13791                        + " not allowed because package " + ii.packageName
13792                        + " does not have a signature matching the target "
13793                        + ii.targetPackage;
13794                reportStartInstrumentationFailure(watcher, className, msg);
13795                throw new SecurityException(msg);
13796            }
13797
13798            final long origId = Binder.clearCallingIdentity();
13799            // Instrumentation can kill and relaunch even persistent processes
13800            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
13801                    "start instr");
13802            ProcessRecord app = addAppLocked(ai, false);
13803            app.instrumentationClass = className;
13804            app.instrumentationInfo = ai;
13805            app.instrumentationProfileFile = profileFile;
13806            app.instrumentationArguments = arguments;
13807            app.instrumentationWatcher = watcher;
13808            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13809            app.instrumentationResultClass = className;
13810            Binder.restoreCallingIdentity(origId);
13811        }
13812
13813        return true;
13814    }
13815
13816    /**
13817     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13818     * error to the logs, but if somebody is watching, send the report there too.  This enables
13819     * the "am" command to report errors with more information.
13820     *
13821     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13822     * @param cn The component name of the instrumentation.
13823     * @param report The error report.
13824     */
13825    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13826            ComponentName cn, String report) {
13827        Slog.w(TAG, report);
13828        try {
13829            if (watcher != null) {
13830                Bundle results = new Bundle();
13831                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13832                results.putString("Error", report);
13833                watcher.instrumentationStatus(cn, -1, results);
13834            }
13835        } catch (RemoteException e) {
13836            Slog.w(TAG, e);
13837        }
13838    }
13839
13840    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13841        if (app.instrumentationWatcher != null) {
13842            try {
13843                // NOTE:  IInstrumentationWatcher *must* be oneway here
13844                app.instrumentationWatcher.instrumentationFinished(
13845                    app.instrumentationClass,
13846                    resultCode,
13847                    results);
13848            } catch (RemoteException e) {
13849            }
13850        }
13851        if (app.instrumentationUiAutomationConnection != null) {
13852            try {
13853                app.instrumentationUiAutomationConnection.shutdown();
13854            } catch (RemoteException re) {
13855                /* ignore */
13856            }
13857            // Only a UiAutomation can set this flag and now that
13858            // it is finished we make sure it is reset to its default.
13859            mUserIsMonkey = false;
13860        }
13861        app.instrumentationWatcher = null;
13862        app.instrumentationUiAutomationConnection = null;
13863        app.instrumentationClass = null;
13864        app.instrumentationInfo = null;
13865        app.instrumentationProfileFile = null;
13866        app.instrumentationArguments = null;
13867
13868        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
13869                "finished inst");
13870    }
13871
13872    public void finishInstrumentation(IApplicationThread target,
13873            int resultCode, Bundle results) {
13874        int userId = UserHandle.getCallingUserId();
13875        // Refuse possible leaked file descriptors
13876        if (results != null && results.hasFileDescriptors()) {
13877            throw new IllegalArgumentException("File descriptors passed in Intent");
13878        }
13879
13880        synchronized(this) {
13881            ProcessRecord app = getRecordForAppLocked(target);
13882            if (app == null) {
13883                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13884                return;
13885            }
13886            final long origId = Binder.clearCallingIdentity();
13887            finishInstrumentationLocked(app, resultCode, results);
13888            Binder.restoreCallingIdentity(origId);
13889        }
13890    }
13891
13892    // =========================================================
13893    // CONFIGURATION
13894    // =========================================================
13895
13896    public ConfigurationInfo getDeviceConfigurationInfo() {
13897        ConfigurationInfo config = new ConfigurationInfo();
13898        synchronized (this) {
13899            config.reqTouchScreen = mConfiguration.touchscreen;
13900            config.reqKeyboardType = mConfiguration.keyboard;
13901            config.reqNavigation = mConfiguration.navigation;
13902            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13903                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13904                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13905            }
13906            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13907                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13908                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13909            }
13910            config.reqGlEsVersion = GL_ES_VERSION;
13911        }
13912        return config;
13913    }
13914
13915    ActivityStack getFocusedStack() {
13916        return mStackSupervisor.getFocusedStack();
13917    }
13918
13919    public Configuration getConfiguration() {
13920        Configuration ci;
13921        synchronized(this) {
13922            ci = new Configuration(mConfiguration);
13923        }
13924        return ci;
13925    }
13926
13927    public void updatePersistentConfiguration(Configuration values) {
13928        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13929                "updateConfiguration()");
13930        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13931                "updateConfiguration()");
13932        if (values == null) {
13933            throw new NullPointerException("Configuration must not be null");
13934        }
13935
13936        synchronized(this) {
13937            final long origId = Binder.clearCallingIdentity();
13938            updateConfigurationLocked(values, null, true, false);
13939            Binder.restoreCallingIdentity(origId);
13940        }
13941    }
13942
13943    public void updateConfiguration(Configuration values) {
13944        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13945                "updateConfiguration()");
13946
13947        synchronized(this) {
13948            if (values == null && mWindowManager != null) {
13949                // sentinel: fetch the current configuration from the window manager
13950                values = mWindowManager.computeNewConfiguration();
13951            }
13952
13953            if (mWindowManager != null) {
13954                mProcessList.applyDisplaySize(mWindowManager);
13955            }
13956
13957            final long origId = Binder.clearCallingIdentity();
13958            if (values != null) {
13959                Settings.System.clearConfiguration(values);
13960            }
13961            updateConfigurationLocked(values, null, false, false);
13962            Binder.restoreCallingIdentity(origId);
13963        }
13964    }
13965
13966    /**
13967     * Do either or both things: (1) change the current configuration, and (2)
13968     * make sure the given activity is running with the (now) current
13969     * configuration.  Returns true if the activity has been left running, or
13970     * false if <var>starting</var> is being destroyed to match the new
13971     * configuration.
13972     * @param persistent TODO
13973     */
13974    boolean updateConfigurationLocked(Configuration values,
13975            ActivityRecord starting, boolean persistent, boolean initLocale) {
13976        int changes = 0;
13977
13978        if (values != null) {
13979            Configuration newConfig = new Configuration(mConfiguration);
13980            changes = newConfig.updateFrom(values);
13981            if (changes != 0) {
13982                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13983                    Slog.i(TAG, "Updating configuration to: " + values);
13984                }
13985
13986                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13987
13988                if (values.locale != null && !initLocale) {
13989                    saveLocaleLocked(values.locale,
13990                                     !values.locale.equals(mConfiguration.locale),
13991                                     values.userSetLocale);
13992                }
13993
13994                mConfigurationSeq++;
13995                if (mConfigurationSeq <= 0) {
13996                    mConfigurationSeq = 1;
13997                }
13998                newConfig.seq = mConfigurationSeq;
13999                mConfiguration = newConfig;
14000                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14001
14002                final Configuration configCopy = new Configuration(mConfiguration);
14003
14004                // TODO: If our config changes, should we auto dismiss any currently
14005                // showing dialogs?
14006                mShowDialogs = shouldShowDialogs(newConfig);
14007
14008                AttributeCache ac = AttributeCache.instance();
14009                if (ac != null) {
14010                    ac.updateConfiguration(configCopy);
14011                }
14012
14013                // Make sure all resources in our process are updated
14014                // right now, so that anyone who is going to retrieve
14015                // resource values after we return will be sure to get
14016                // the new ones.  This is especially important during
14017                // boot, where the first config change needs to guarantee
14018                // all resources have that config before following boot
14019                // code is executed.
14020                sSystemThread.applyConfigurationToResources(configCopy);
14021
14022                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14023                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14024                    msg.obj = new Configuration(configCopy);
14025                    mHandler.sendMessage(msg);
14026                }
14027
14028                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14029                    ProcessRecord app = mLruProcesses.get(i);
14030                    try {
14031                        if (app.thread != null) {
14032                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14033                                    + app.processName + " new config " + mConfiguration);
14034                            app.thread.scheduleConfigurationChanged(configCopy);
14035                        }
14036                    } catch (Exception e) {
14037                    }
14038                }
14039                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14040                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14041                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14042                        | Intent.FLAG_RECEIVER_FOREGROUND);
14043                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14044                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14045                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14046                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14047                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14048                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14049                    broadcastIntentLocked(null, null, intent,
14050                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14051                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14052                }
14053            }
14054        }
14055
14056        boolean kept = true;
14057        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14058        // mainStack is null during startup.
14059        if (mainStack != null) {
14060            if (changes != 0 && starting == null) {
14061                // If the configuration changed, and the caller is not already
14062                // in the process of starting an activity, then find the top
14063                // activity to check if its configuration needs to change.
14064                starting = mainStack.topRunningActivityLocked(null);
14065            }
14066
14067            if (starting != null) {
14068                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14069                // And we need to make sure at this point that all other activities
14070                // are made visible with the correct configuration.
14071                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14072            }
14073        }
14074
14075        if (values != null && mWindowManager != null) {
14076            mWindowManager.setNewConfiguration(mConfiguration);
14077        }
14078
14079        return kept;
14080    }
14081
14082    /**
14083     * Decide based on the configuration whether we should shouw the ANR,
14084     * crash, etc dialogs.  The idea is that if there is no affordnace to
14085     * press the on-screen buttons, we shouldn't show the dialog.
14086     *
14087     * A thought: SystemUI might also want to get told about this, the Power
14088     * dialog / global actions also might want different behaviors.
14089     */
14090    private static final boolean shouldShowDialogs(Configuration config) {
14091        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14092                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14093    }
14094
14095    /**
14096     * Save the locale.  You must be inside a synchronized (this) block.
14097     */
14098    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14099        if(isDiff) {
14100            SystemProperties.set("user.language", l.getLanguage());
14101            SystemProperties.set("user.region", l.getCountry());
14102        }
14103
14104        if(isPersist) {
14105            SystemProperties.set("persist.sys.language", l.getLanguage());
14106            SystemProperties.set("persist.sys.country", l.getCountry());
14107            SystemProperties.set("persist.sys.localevar", l.getVariant());
14108        }
14109    }
14110
14111    @Override
14112    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14113        ActivityRecord srec = ActivityRecord.forToken(token);
14114        return srec != null && srec.task.affinity != null &&
14115                srec.task.affinity.equals(destAffinity);
14116    }
14117
14118    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14119            Intent resultData) {
14120
14121        synchronized (this) {
14122            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14123            if (stack != null) {
14124                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14125            }
14126            return false;
14127        }
14128    }
14129
14130    public int getLaunchedFromUid(IBinder activityToken) {
14131        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14132        if (srec == null) {
14133            return -1;
14134        }
14135        return srec.launchedFromUid;
14136    }
14137
14138    public String getLaunchedFromPackage(IBinder activityToken) {
14139        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14140        if (srec == null) {
14141            return null;
14142        }
14143        return srec.launchedFromPackage;
14144    }
14145
14146    // =========================================================
14147    // LIFETIME MANAGEMENT
14148    // =========================================================
14149
14150    // Returns which broadcast queue the app is the current [or imminent] receiver
14151    // on, or 'null' if the app is not an active broadcast recipient.
14152    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14153        BroadcastRecord r = app.curReceiver;
14154        if (r != null) {
14155            return r.queue;
14156        }
14157
14158        // It's not the current receiver, but it might be starting up to become one
14159        synchronized (this) {
14160            for (BroadcastQueue queue : mBroadcastQueues) {
14161                r = queue.mPendingBroadcast;
14162                if (r != null && r.curApp == app) {
14163                    // found it; report which queue it's in
14164                    return queue;
14165                }
14166            }
14167        }
14168
14169        return null;
14170    }
14171
14172    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14173            boolean doingAll, long now) {
14174        if (mAdjSeq == app.adjSeq) {
14175            // This adjustment has already been computed.
14176            return app.curRawAdj;
14177        }
14178
14179        if (app.thread == null) {
14180            app.adjSeq = mAdjSeq;
14181            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14182            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14183            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14184        }
14185
14186        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14187        app.adjSource = null;
14188        app.adjTarget = null;
14189        app.empty = false;
14190        app.cached = false;
14191
14192        final int activitiesSize = app.activities.size();
14193
14194        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14195            // The max adjustment doesn't allow this app to be anything
14196            // below foreground, so it is not worth doing work for it.
14197            app.adjType = "fixed";
14198            app.adjSeq = mAdjSeq;
14199            app.curRawAdj = app.maxAdj;
14200            app.foregroundActivities = false;
14201            app.keeping = true;
14202            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14203            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14204            // System process can do UI, and when they do we want to have
14205            // them trim their memory after the user leaves the UI.  To
14206            // facilitate this, here we need to determine whether or not it
14207            // is currently showing UI.
14208            app.systemNoUi = true;
14209            if (app == TOP_APP) {
14210                app.systemNoUi = false;
14211            } else if (activitiesSize > 0) {
14212                for (int j = 0; j < activitiesSize; j++) {
14213                    final ActivityRecord r = app.activities.get(j);
14214                    if (r.visible) {
14215                        app.systemNoUi = false;
14216                    }
14217                }
14218            }
14219            if (!app.systemNoUi) {
14220                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14221            }
14222            return (app.curAdj=app.maxAdj);
14223        }
14224
14225        app.keeping = false;
14226        app.systemNoUi = false;
14227
14228        // Determine the importance of the process, starting with most
14229        // important to least, and assign an appropriate OOM adjustment.
14230        int adj;
14231        int schedGroup;
14232        int procState;
14233        boolean foregroundActivities = false;
14234        boolean interesting = false;
14235        BroadcastQueue queue;
14236        if (app == TOP_APP) {
14237            // The last app on the list is the foreground app.
14238            adj = ProcessList.FOREGROUND_APP_ADJ;
14239            schedGroup = Process.THREAD_GROUP_DEFAULT;
14240            app.adjType = "top-activity";
14241            foregroundActivities = true;
14242            interesting = true;
14243            procState = ActivityManager.PROCESS_STATE_TOP;
14244        } else if (app.instrumentationClass != null) {
14245            // Don't want to kill running instrumentation.
14246            adj = ProcessList.FOREGROUND_APP_ADJ;
14247            schedGroup = Process.THREAD_GROUP_DEFAULT;
14248            app.adjType = "instrumentation";
14249            interesting = true;
14250            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14251        } else if ((queue = isReceivingBroadcast(app)) != null) {
14252            // An app that is currently receiving a broadcast also
14253            // counts as being in the foreground for OOM killer purposes.
14254            // It's placed in a sched group based on the nature of the
14255            // broadcast as reflected by which queue it's active in.
14256            adj = ProcessList.FOREGROUND_APP_ADJ;
14257            schedGroup = (queue == mFgBroadcastQueue)
14258                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14259            app.adjType = "broadcast";
14260            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14261        } else if (app.executingServices.size() > 0) {
14262            // An app that is currently executing a service callback also
14263            // counts as being in the foreground.
14264            adj = ProcessList.FOREGROUND_APP_ADJ;
14265            schedGroup = app.execServicesFg ?
14266                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14267            app.adjType = "exec-service";
14268            procState = ActivityManager.PROCESS_STATE_SERVICE;
14269            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14270        } else {
14271            // As far as we know the process is empty.  We may change our mind later.
14272            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14273            // At this point we don't actually know the adjustment.  Use the cached adj
14274            // value that the caller wants us to.
14275            adj = cachedAdj;
14276            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14277            app.cached = true;
14278            app.empty = true;
14279            app.adjType = "cch-empty";
14280        }
14281
14282        // Examine all activities if not already foreground.
14283        if (!foregroundActivities && activitiesSize > 0) {
14284            for (int j = 0; j < activitiesSize; j++) {
14285                final ActivityRecord r = app.activities.get(j);
14286                if (r.app != app) {
14287                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14288                            + app + "?!?");
14289                    continue;
14290                }
14291                if (r.visible) {
14292                    // App has a visible activity; only upgrade adjustment.
14293                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14294                        adj = ProcessList.VISIBLE_APP_ADJ;
14295                        app.adjType = "visible";
14296                    }
14297                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14298                        procState = ActivityManager.PROCESS_STATE_TOP;
14299                    }
14300                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14301                    app.cached = false;
14302                    app.empty = false;
14303                    foregroundActivities = true;
14304                    break;
14305                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14306                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14307                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14308                        app.adjType = "pausing";
14309                    }
14310                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14311                        procState = ActivityManager.PROCESS_STATE_TOP;
14312                    }
14313                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14314                    app.cached = false;
14315                    app.empty = false;
14316                    foregroundActivities = true;
14317                } else if (r.state == ActivityState.STOPPING) {
14318                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14319                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14320                        app.adjType = "stopping";
14321                    }
14322                    // For the process state, we will at this point consider the
14323                    // process to be cached.  It will be cached either as an activity
14324                    // or empty depending on whether the activity is finishing.  We do
14325                    // this so that we can treat the process as cached for purposes of
14326                    // memory trimming (determing current memory level, trim command to
14327                    // send to process) since there can be an arbitrary number of stopping
14328                    // processes and they should soon all go into the cached state.
14329                    if (!r.finishing) {
14330                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14331                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14332                        }
14333                    }
14334                    app.cached = false;
14335                    app.empty = false;
14336                    foregroundActivities = true;
14337                } else {
14338                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14339                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14340                        app.adjType = "cch-act";
14341                    }
14342                }
14343            }
14344        }
14345
14346        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14347            if (app.foregroundServices) {
14348                // The user is aware of this app, so make it visible.
14349                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14350                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14351                app.cached = false;
14352                app.adjType = "fg-service";
14353                schedGroup = Process.THREAD_GROUP_DEFAULT;
14354            } else if (app.forcingToForeground != null) {
14355                // The user is aware of this app, so make it visible.
14356                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14357                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14358                app.cached = false;
14359                app.adjType = "force-fg";
14360                app.adjSource = app.forcingToForeground;
14361                schedGroup = Process.THREAD_GROUP_DEFAULT;
14362            }
14363        }
14364
14365        if (app.foregroundServices) {
14366            interesting = true;
14367        }
14368
14369        if (app == mHeavyWeightProcess) {
14370            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14371                // We don't want to kill the current heavy-weight process.
14372                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14373                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14374                app.cached = false;
14375                app.adjType = "heavy";
14376            }
14377            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14378                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14379            }
14380        }
14381
14382        if (app == mHomeProcess) {
14383            if (adj > ProcessList.HOME_APP_ADJ) {
14384                // This process is hosting what we currently consider to be the
14385                // home app, so we don't want to let it go into the background.
14386                adj = ProcessList.HOME_APP_ADJ;
14387                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14388                app.cached = false;
14389                app.adjType = "home";
14390            }
14391            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14392                procState = ActivityManager.PROCESS_STATE_HOME;
14393            }
14394        }
14395
14396        if (app == mPreviousProcess && app.activities.size() > 0) {
14397            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14398                // This was the previous process that showed UI to the user.
14399                // We want to try to keep it around more aggressively, to give
14400                // a good experience around switching between two apps.
14401                adj = ProcessList.PREVIOUS_APP_ADJ;
14402                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14403                app.cached = false;
14404                app.adjType = "previous";
14405            }
14406            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14407                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14408            }
14409        }
14410
14411        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14412                + " reason=" + app.adjType);
14413
14414        // By default, we use the computed adjustment.  It may be changed if
14415        // there are applications dependent on our services or providers, but
14416        // this gives us a baseline and makes sure we don't get into an
14417        // infinite recursion.
14418        app.adjSeq = mAdjSeq;
14419        app.curRawAdj = adj;
14420        app.hasStartedServices = false;
14421
14422        if (mBackupTarget != null && app == mBackupTarget.app) {
14423            // If possible we want to avoid killing apps while they're being backed up
14424            if (adj > ProcessList.BACKUP_APP_ADJ) {
14425                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14426                adj = ProcessList.BACKUP_APP_ADJ;
14427                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14428                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14429                }
14430                app.adjType = "backup";
14431                app.cached = false;
14432            }
14433            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14434                procState = ActivityManager.PROCESS_STATE_BACKUP;
14435            }
14436        }
14437
14438        boolean mayBeTop = false;
14439
14440        for (int is = app.services.size()-1;
14441                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14442                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14443                        || procState > ActivityManager.PROCESS_STATE_TOP);
14444                is--) {
14445            ServiceRecord s = app.services.valueAt(is);
14446            if (s.startRequested) {
14447                app.hasStartedServices = true;
14448                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14449                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14450                }
14451                if (app.hasShownUi && app != mHomeProcess) {
14452                    // If this process has shown some UI, let it immediately
14453                    // go to the LRU list because it may be pretty heavy with
14454                    // UI stuff.  We'll tag it with a label just to help
14455                    // debug and understand what is going on.
14456                    if (adj > ProcessList.SERVICE_ADJ) {
14457                        app.adjType = "cch-started-ui-services";
14458                    }
14459                } else {
14460                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14461                        // This service has seen some activity within
14462                        // recent memory, so we will keep its process ahead
14463                        // of the background processes.
14464                        if (adj > ProcessList.SERVICE_ADJ) {
14465                            adj = ProcessList.SERVICE_ADJ;
14466                            app.adjType = "started-services";
14467                            app.cached = false;
14468                        }
14469                    }
14470                    // If we have let the service slide into the background
14471                    // state, still have some text describing what it is doing
14472                    // even though the service no longer has an impact.
14473                    if (adj > ProcessList.SERVICE_ADJ) {
14474                        app.adjType = "cch-started-services";
14475                    }
14476                }
14477                // Don't kill this process because it is doing work; it
14478                // has said it is doing work.
14479                app.keeping = true;
14480            }
14481            for (int conni = s.connections.size()-1;
14482                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14483                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14484                            || procState > ActivityManager.PROCESS_STATE_TOP);
14485                    conni--) {
14486                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14487                for (int i = 0;
14488                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14489                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14490                                || procState > ActivityManager.PROCESS_STATE_TOP);
14491                        i++) {
14492                    // XXX should compute this based on the max of
14493                    // all connected clients.
14494                    ConnectionRecord cr = clist.get(i);
14495                    if (cr.binding.client == app) {
14496                        // Binding to ourself is not interesting.
14497                        continue;
14498                    }
14499                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14500                        ProcessRecord client = cr.binding.client;
14501                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14502                                TOP_APP, doingAll, now);
14503                        int clientProcState = client.curProcState;
14504                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14505                            // If the other app is cached for any reason, for purposes here
14506                            // we are going to consider it empty.  The specific cached state
14507                            // doesn't propagate except under certain conditions.
14508                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14509                        }
14510                        String adjType = null;
14511                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14512                            // Not doing bind OOM management, so treat
14513                            // this guy more like a started service.
14514                            if (app.hasShownUi && app != mHomeProcess) {
14515                                // If this process has shown some UI, let it immediately
14516                                // go to the LRU list because it may be pretty heavy with
14517                                // UI stuff.  We'll tag it with a label just to help
14518                                // debug and understand what is going on.
14519                                if (adj > clientAdj) {
14520                                    adjType = "cch-bound-ui-services";
14521                                }
14522                                app.cached = false;
14523                                clientAdj = adj;
14524                                clientProcState = procState;
14525                            } else {
14526                                if (now >= (s.lastActivity
14527                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14528                                    // This service has not seen activity within
14529                                    // recent memory, so allow it to drop to the
14530                                    // LRU list if there is no other reason to keep
14531                                    // it around.  We'll also tag it with a label just
14532                                    // to help debug and undertand what is going on.
14533                                    if (adj > clientAdj) {
14534                                        adjType = "cch-bound-services";
14535                                    }
14536                                    clientAdj = adj;
14537                                }
14538                            }
14539                        }
14540                        if (adj > clientAdj) {
14541                            // If this process has recently shown UI, and
14542                            // the process that is binding to it is less
14543                            // important than being visible, then we don't
14544                            // care about the binding as much as we care
14545                            // about letting this process get into the LRU
14546                            // list to be killed and restarted if needed for
14547                            // memory.
14548                            if (app.hasShownUi && app != mHomeProcess
14549                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14550                                adjType = "cch-bound-ui-services";
14551                            } else {
14552                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14553                                        |Context.BIND_IMPORTANT)) != 0) {
14554                                    adj = clientAdj;
14555                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14556                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14557                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14558                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14559                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14560                                    adj = clientAdj;
14561                                } else {
14562                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14563                                        adj = ProcessList.VISIBLE_APP_ADJ;
14564                                    }
14565                                }
14566                                if (!client.cached) {
14567                                    app.cached = false;
14568                                }
14569                                if (client.keeping) {
14570                                    app.keeping = true;
14571                                }
14572                                adjType = "service";
14573                            }
14574                        }
14575                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14576                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14577                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14578                            }
14579                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14580                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14581                                    // Special handling of clients who are in the top state.
14582                                    // We *may* want to consider this process to be in the
14583                                    // top state as well, but only if there is not another
14584                                    // reason for it to be running.  Being on the top is a
14585                                    // special state, meaning you are specifically running
14586                                    // for the current top app.  If the process is already
14587                                    // running in the background for some other reason, it
14588                                    // is more important to continue considering it to be
14589                                    // in the background state.
14590                                    mayBeTop = true;
14591                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14592                                } else {
14593                                    // Special handling for above-top states (persistent
14594                                    // processes).  These should not bring the current process
14595                                    // into the top state, since they are not on top.  Instead
14596                                    // give them the best state after that.
14597                                    clientProcState =
14598                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14599                                }
14600                            }
14601                        } else {
14602                            if (clientProcState <
14603                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14604                                clientProcState =
14605                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14606                            }
14607                        }
14608                        if (procState > clientProcState) {
14609                            procState = clientProcState;
14610                        }
14611                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14612                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14613                            app.pendingUiClean = true;
14614                        }
14615                        if (adjType != null) {
14616                            app.adjType = adjType;
14617                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14618                                    .REASON_SERVICE_IN_USE;
14619                            app.adjSource = cr.binding.client;
14620                            app.adjSourceOom = clientAdj;
14621                            app.adjTarget = s.name;
14622                        }
14623                    }
14624                    final ActivityRecord a = cr.activity;
14625                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14626                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14627                                (a.visible || a.state == ActivityState.RESUMED
14628                                 || a.state == ActivityState.PAUSING)) {
14629                            adj = ProcessList.FOREGROUND_APP_ADJ;
14630                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14631                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14632                            }
14633                            app.cached = false;
14634                            app.adjType = "service";
14635                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14636                                    .REASON_SERVICE_IN_USE;
14637                            app.adjSource = a;
14638                            app.adjSourceOom = adj;
14639                            app.adjTarget = s.name;
14640                        }
14641                    }
14642                }
14643            }
14644        }
14645
14646        for (int provi = app.pubProviders.size()-1;
14647                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14648                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14649                        || procState > ActivityManager.PROCESS_STATE_TOP);
14650                provi--) {
14651            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14652            for (int i = cpr.connections.size()-1;
14653                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14654                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14655                            || procState > ActivityManager.PROCESS_STATE_TOP);
14656                    i--) {
14657                ContentProviderConnection conn = cpr.connections.get(i);
14658                ProcessRecord client = conn.client;
14659                if (client == app) {
14660                    // Being our own client is not interesting.
14661                    continue;
14662                }
14663                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14664                int clientProcState = client.curProcState;
14665                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14666                    // If the other app is cached for any reason, for purposes here
14667                    // we are going to consider it empty.
14668                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14669                }
14670                if (adj > clientAdj) {
14671                    if (app.hasShownUi && app != mHomeProcess
14672                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14673                        app.adjType = "cch-ui-provider";
14674                    } else {
14675                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14676                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14677                        app.adjType = "provider";
14678                    }
14679                    app.cached &= client.cached;
14680                    app.keeping |= client.keeping;
14681                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14682                            .REASON_PROVIDER_IN_USE;
14683                    app.adjSource = client;
14684                    app.adjSourceOom = clientAdj;
14685                    app.adjTarget = cpr.name;
14686                }
14687                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14688                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14689                        // Special handling of clients who are in the top state.
14690                        // We *may* want to consider this process to be in the
14691                        // top state as well, but only if there is not another
14692                        // reason for it to be running.  Being on the top is a
14693                        // special state, meaning you are specifically running
14694                        // for the current top app.  If the process is already
14695                        // running in the background for some other reason, it
14696                        // is more important to continue considering it to be
14697                        // in the background state.
14698                        mayBeTop = true;
14699                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14700                    } else {
14701                        // Special handling for above-top states (persistent
14702                        // processes).  These should not bring the current process
14703                        // into the top state, since they are not on top.  Instead
14704                        // give them the best state after that.
14705                        clientProcState =
14706                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14707                    }
14708                }
14709                if (procState > clientProcState) {
14710                    procState = clientProcState;
14711                }
14712                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14713                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14714                }
14715            }
14716            // If the provider has external (non-framework) process
14717            // dependencies, ensure that its adjustment is at least
14718            // FOREGROUND_APP_ADJ.
14719            if (cpr.hasExternalProcessHandles()) {
14720                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14721                    adj = ProcessList.FOREGROUND_APP_ADJ;
14722                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14723                    app.cached = false;
14724                    app.keeping = true;
14725                    app.adjType = "provider";
14726                    app.adjTarget = cpr.name;
14727                }
14728                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14729                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14730                }
14731            }
14732        }
14733
14734        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14735            // A client of one of our services or providers is in the top state.  We
14736            // *may* want to be in the top state, but not if we are already running in
14737            // the background for some other reason.  For the decision here, we are going
14738            // to pick out a few specific states that we want to remain in when a client
14739            // is top (states that tend to be longer-term) and otherwise allow it to go
14740            // to the top state.
14741            switch (procState) {
14742                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14743                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14744                case ActivityManager.PROCESS_STATE_SERVICE:
14745                    // These all are longer-term states, so pull them up to the top
14746                    // of the background states, but not all the way to the top state.
14747                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14748                    break;
14749                default:
14750                    // Otherwise, top is a better choice, so take it.
14751                    procState = ActivityManager.PROCESS_STATE_TOP;
14752                    break;
14753            }
14754        }
14755
14756        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14757            // This is a cached process, but with client activities.  Mark it so.
14758            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14759            app.adjType = "cch-client-act";
14760        }
14761
14762        if (adj == ProcessList.SERVICE_ADJ) {
14763            if (doingAll) {
14764                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14765                mNewNumServiceProcs++;
14766                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14767                if (!app.serviceb) {
14768                    // This service isn't far enough down on the LRU list to
14769                    // normally be a B service, but if we are low on RAM and it
14770                    // is large we want to force it down since we would prefer to
14771                    // keep launcher over it.
14772                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14773                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14774                        app.serviceHighRam = true;
14775                        app.serviceb = true;
14776                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14777                    } else {
14778                        mNewNumAServiceProcs++;
14779                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14780                    }
14781                } else {
14782                    app.serviceHighRam = false;
14783                }
14784            }
14785            if (app.serviceb) {
14786                adj = ProcessList.SERVICE_B_ADJ;
14787            }
14788        }
14789
14790        app.curRawAdj = adj;
14791
14792        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14793        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14794        if (adj > app.maxAdj) {
14795            adj = app.maxAdj;
14796            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14797                schedGroup = Process.THREAD_GROUP_DEFAULT;
14798            }
14799        }
14800        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14801            app.keeping = true;
14802        }
14803
14804        // Do final modification to adj.  Everything we do between here and applying
14805        // the final setAdj must be done in this function, because we will also use
14806        // it when computing the final cached adj later.  Note that we don't need to
14807        // worry about this for max adj above, since max adj will always be used to
14808        // keep it out of the cached vaues.
14809        adj = app.modifyRawOomAdj(adj);
14810
14811        app.curProcState = procState;
14812
14813        int importance = app.memImportance;
14814        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14815            app.curAdj = adj;
14816            app.curSchedGroup = schedGroup;
14817            if (!interesting) {
14818                // For this reporting, if there is not something explicitly
14819                // interesting in this process then we will push it to the
14820                // background importance.
14821                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14822            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14823                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14824            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14825                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14826            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14827                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14828            } else if (adj >= ProcessList.SERVICE_ADJ) {
14829                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14830            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14831                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14832            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14833                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14834            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14835                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14836            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14837                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14838            } else {
14839                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14840            }
14841        }
14842
14843        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14844        if (foregroundActivities != app.foregroundActivities) {
14845            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14846        }
14847        if (changes != 0) {
14848            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14849            app.memImportance = importance;
14850            app.foregroundActivities = foregroundActivities;
14851            int i = mPendingProcessChanges.size()-1;
14852            ProcessChangeItem item = null;
14853            while (i >= 0) {
14854                item = mPendingProcessChanges.get(i);
14855                if (item.pid == app.pid) {
14856                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14857                    break;
14858                }
14859                i--;
14860            }
14861            if (i < 0) {
14862                // No existing item in pending changes; need a new one.
14863                final int NA = mAvailProcessChanges.size();
14864                if (NA > 0) {
14865                    item = mAvailProcessChanges.remove(NA-1);
14866                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14867                } else {
14868                    item = new ProcessChangeItem();
14869                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14870                }
14871                item.changes = 0;
14872                item.pid = app.pid;
14873                item.uid = app.info.uid;
14874                if (mPendingProcessChanges.size() == 0) {
14875                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14876                            "*** Enqueueing dispatch processes changed!");
14877                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14878                }
14879                mPendingProcessChanges.add(item);
14880            }
14881            item.changes |= changes;
14882            item.importance = importance;
14883            item.foregroundActivities = foregroundActivities;
14884            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14885                    + Integer.toHexString(System.identityHashCode(item))
14886                    + " " + app.toShortString() + ": changes=" + item.changes
14887                    + " importance=" + item.importance
14888                    + " foreground=" + item.foregroundActivities
14889                    + " type=" + app.adjType + " source=" + app.adjSource
14890                    + " target=" + app.adjTarget);
14891        }
14892
14893        return app.curRawAdj;
14894    }
14895
14896    /**
14897     * Schedule PSS collection of a process.
14898     */
14899    void requestPssLocked(ProcessRecord proc, int procState) {
14900        if (mPendingPssProcesses.contains(proc)) {
14901            return;
14902        }
14903        if (mPendingPssProcesses.size() == 0) {
14904            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14905        }
14906        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14907        proc.pssProcState = procState;
14908        mPendingPssProcesses.add(proc);
14909    }
14910
14911    /**
14912     * Schedule PSS collection of all processes.
14913     */
14914    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14915        if (!always) {
14916            if (now < (mLastFullPssTime +
14917                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14918                return;
14919            }
14920        }
14921        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14922        mLastFullPssTime = now;
14923        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14924        mPendingPssProcesses.clear();
14925        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14926            ProcessRecord app = mLruProcesses.get(i);
14927            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14928                app.pssProcState = app.setProcState;
14929                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14930                        mSleeping, now);
14931                mPendingPssProcesses.add(app);
14932            }
14933        }
14934        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14935    }
14936
14937    /**
14938     * Ask a given process to GC right now.
14939     */
14940    final void performAppGcLocked(ProcessRecord app) {
14941        try {
14942            app.lastRequestedGc = SystemClock.uptimeMillis();
14943            if (app.thread != null) {
14944                if (app.reportLowMemory) {
14945                    app.reportLowMemory = false;
14946                    app.thread.scheduleLowMemory();
14947                } else {
14948                    app.thread.processInBackground();
14949                }
14950            }
14951        } catch (Exception e) {
14952            // whatever.
14953        }
14954    }
14955
14956    /**
14957     * Returns true if things are idle enough to perform GCs.
14958     */
14959    private final boolean canGcNowLocked() {
14960        boolean processingBroadcasts = false;
14961        for (BroadcastQueue q : mBroadcastQueues) {
14962            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14963                processingBroadcasts = true;
14964            }
14965        }
14966        return !processingBroadcasts
14967                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14968    }
14969
14970    /**
14971     * Perform GCs on all processes that are waiting for it, but only
14972     * if things are idle.
14973     */
14974    final void performAppGcsLocked() {
14975        final int N = mProcessesToGc.size();
14976        if (N <= 0) {
14977            return;
14978        }
14979        if (canGcNowLocked()) {
14980            while (mProcessesToGc.size() > 0) {
14981                ProcessRecord proc = mProcessesToGc.remove(0);
14982                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14983                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14984                            <= SystemClock.uptimeMillis()) {
14985                        // To avoid spamming the system, we will GC processes one
14986                        // at a time, waiting a few seconds between each.
14987                        performAppGcLocked(proc);
14988                        scheduleAppGcsLocked();
14989                        return;
14990                    } else {
14991                        // It hasn't been long enough since we last GCed this
14992                        // process...  put it in the list to wait for its time.
14993                        addProcessToGcListLocked(proc);
14994                        break;
14995                    }
14996                }
14997            }
14998
14999            scheduleAppGcsLocked();
15000        }
15001    }
15002
15003    /**
15004     * If all looks good, perform GCs on all processes waiting for them.
15005     */
15006    final void performAppGcsIfAppropriateLocked() {
15007        if (canGcNowLocked()) {
15008            performAppGcsLocked();
15009            return;
15010        }
15011        // Still not idle, wait some more.
15012        scheduleAppGcsLocked();
15013    }
15014
15015    /**
15016     * Schedule the execution of all pending app GCs.
15017     */
15018    final void scheduleAppGcsLocked() {
15019        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15020
15021        if (mProcessesToGc.size() > 0) {
15022            // Schedule a GC for the time to the next process.
15023            ProcessRecord proc = mProcessesToGc.get(0);
15024            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15025
15026            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15027            long now = SystemClock.uptimeMillis();
15028            if (when < (now+GC_TIMEOUT)) {
15029                when = now + GC_TIMEOUT;
15030            }
15031            mHandler.sendMessageAtTime(msg, when);
15032        }
15033    }
15034
15035    /**
15036     * Add a process to the array of processes waiting to be GCed.  Keeps the
15037     * list in sorted order by the last GC time.  The process can't already be
15038     * on the list.
15039     */
15040    final void addProcessToGcListLocked(ProcessRecord proc) {
15041        boolean added = false;
15042        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15043            if (mProcessesToGc.get(i).lastRequestedGc <
15044                    proc.lastRequestedGc) {
15045                added = true;
15046                mProcessesToGc.add(i+1, proc);
15047                break;
15048            }
15049        }
15050        if (!added) {
15051            mProcessesToGc.add(0, proc);
15052        }
15053    }
15054
15055    /**
15056     * Set up to ask a process to GC itself.  This will either do it
15057     * immediately, or put it on the list of processes to gc the next
15058     * time things are idle.
15059     */
15060    final void scheduleAppGcLocked(ProcessRecord app) {
15061        long now = SystemClock.uptimeMillis();
15062        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15063            return;
15064        }
15065        if (!mProcessesToGc.contains(app)) {
15066            addProcessToGcListLocked(app);
15067            scheduleAppGcsLocked();
15068        }
15069    }
15070
15071    final void checkExcessivePowerUsageLocked(boolean doKills) {
15072        updateCpuStatsNow();
15073
15074        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15075        boolean doWakeKills = doKills;
15076        boolean doCpuKills = doKills;
15077        if (mLastPowerCheckRealtime == 0) {
15078            doWakeKills = false;
15079        }
15080        if (mLastPowerCheckUptime == 0) {
15081            doCpuKills = false;
15082        }
15083        if (stats.isScreenOn()) {
15084            doWakeKills = false;
15085        }
15086        final long curRealtime = SystemClock.elapsedRealtime();
15087        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15088        final long curUptime = SystemClock.uptimeMillis();
15089        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15090        mLastPowerCheckRealtime = curRealtime;
15091        mLastPowerCheckUptime = curUptime;
15092        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15093            doWakeKills = false;
15094        }
15095        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15096            doCpuKills = false;
15097        }
15098        int i = mLruProcesses.size();
15099        while (i > 0) {
15100            i--;
15101            ProcessRecord app = mLruProcesses.get(i);
15102            if (!app.keeping) {
15103                long wtime;
15104                synchronized (stats) {
15105                    wtime = stats.getProcessWakeTime(app.info.uid,
15106                            app.pid, curRealtime);
15107                }
15108                long wtimeUsed = wtime - app.lastWakeTime;
15109                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15110                if (DEBUG_POWER) {
15111                    StringBuilder sb = new StringBuilder(128);
15112                    sb.append("Wake for ");
15113                    app.toShortString(sb);
15114                    sb.append(": over ");
15115                    TimeUtils.formatDuration(realtimeSince, sb);
15116                    sb.append(" used ");
15117                    TimeUtils.formatDuration(wtimeUsed, sb);
15118                    sb.append(" (");
15119                    sb.append((wtimeUsed*100)/realtimeSince);
15120                    sb.append("%)");
15121                    Slog.i(TAG, sb.toString());
15122                    sb.setLength(0);
15123                    sb.append("CPU for ");
15124                    app.toShortString(sb);
15125                    sb.append(": over ");
15126                    TimeUtils.formatDuration(uptimeSince, sb);
15127                    sb.append(" used ");
15128                    TimeUtils.formatDuration(cputimeUsed, sb);
15129                    sb.append(" (");
15130                    sb.append((cputimeUsed*100)/uptimeSince);
15131                    sb.append("%)");
15132                    Slog.i(TAG, sb.toString());
15133                }
15134                // If a process has held a wake lock for more
15135                // than 50% of the time during this period,
15136                // that sounds bad.  Kill!
15137                if (doWakeKills && realtimeSince > 0
15138                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15139                    synchronized (stats) {
15140                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15141                                realtimeSince, wtimeUsed);
15142                    }
15143                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15144                            + " during " + realtimeSince);
15145                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15146                } else if (doCpuKills && uptimeSince > 0
15147                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15148                    synchronized (stats) {
15149                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15150                                uptimeSince, cputimeUsed);
15151                    }
15152                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15153                            + " during " + uptimeSince);
15154                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15155                } else {
15156                    app.lastWakeTime = wtime;
15157                    app.lastCpuTime = app.curCpuTime;
15158                }
15159            }
15160        }
15161    }
15162
15163    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15164            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15165        boolean success = true;
15166
15167        if (app.curRawAdj != app.setRawAdj) {
15168            if (wasKeeping && !app.keeping) {
15169                // This app is no longer something we want to keep.  Note
15170                // its current wake lock time to later know to kill it if
15171                // it is not behaving well.
15172                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15173                synchronized (stats) {
15174                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15175                            app.pid, SystemClock.elapsedRealtime());
15176                }
15177                app.lastCpuTime = app.curCpuTime;
15178            }
15179
15180            app.setRawAdj = app.curRawAdj;
15181        }
15182
15183        if (app.curAdj != app.setAdj) {
15184            ProcessList.setOomAdj(app.pid, app.curAdj);
15185            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15186                TAG, "Set " + app.pid + " " + app.processName +
15187                " adj " + app.curAdj + ": " + app.adjType);
15188            app.setAdj = app.curAdj;
15189        }
15190
15191        if (app.setSchedGroup != app.curSchedGroup) {
15192            app.setSchedGroup = app.curSchedGroup;
15193            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15194                    "Setting process group of " + app.processName
15195                    + " to " + app.curSchedGroup);
15196            if (app.waitingToKill != null &&
15197                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15198                killUnneededProcessLocked(app, app.waitingToKill);
15199                success = false;
15200            } else {
15201                if (true) {
15202                    long oldId = Binder.clearCallingIdentity();
15203                    try {
15204                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15205                    } catch (Exception e) {
15206                        Slog.w(TAG, "Failed setting process group of " + app.pid
15207                                + " to " + app.curSchedGroup);
15208                        e.printStackTrace();
15209                    } finally {
15210                        Binder.restoreCallingIdentity(oldId);
15211                    }
15212                } else {
15213                    if (app.thread != null) {
15214                        try {
15215                            app.thread.setSchedulingGroup(app.curSchedGroup);
15216                        } catch (RemoteException e) {
15217                        }
15218                    }
15219                }
15220                Process.setSwappiness(app.pid,
15221                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15222            }
15223        }
15224        if (app.repProcState != app.curProcState) {
15225            app.repProcState = app.curProcState;
15226            if (!reportingProcessState && app.thread != null) {
15227                try {
15228                    if (false) {
15229                        //RuntimeException h = new RuntimeException("here");
15230                        Slog.i(TAG, "Sending new process state " + app.repProcState
15231                                + " to " + app /*, h*/);
15232                    }
15233                    app.thread.setProcessState(app.repProcState);
15234                } catch (RemoteException e) {
15235                }
15236            }
15237        }
15238        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15239                app.setProcState)) {
15240            app.lastStateTime = now;
15241            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15242                    mSleeping, now);
15243            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15244                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15245                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15246                    + (app.nextPssTime-now) + ": " + app);
15247        } else {
15248            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15249                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15250                requestPssLocked(app, app.setProcState);
15251                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15252                        mSleeping, now);
15253            } else if (false && DEBUG_PSS) {
15254                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15255            }
15256        }
15257        if (app.setProcState != app.curProcState) {
15258            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15259                    "Proc state change of " + app.processName
15260                    + " to " + app.curProcState);
15261            app.setProcState = app.curProcState;
15262            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15263                app.notCachedSinceIdle = false;
15264            }
15265            if (!doingAll) {
15266                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15267            } else {
15268                app.procStateChanged = true;
15269            }
15270        }
15271        return success;
15272    }
15273
15274    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15275        if (proc.thread != null && proc.baseProcessTracker != null) {
15276            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15277        }
15278    }
15279
15280    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15281            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15282        if (app.thread == null) {
15283            return false;
15284        }
15285
15286        final boolean wasKeeping = app.keeping;
15287
15288        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15289
15290        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15291                reportingProcessState, now);
15292    }
15293
15294    private final ActivityRecord resumedAppLocked() {
15295        return mStackSupervisor.resumedAppLocked();
15296    }
15297
15298    final boolean updateOomAdjLocked(ProcessRecord app) {
15299        return updateOomAdjLocked(app, false);
15300    }
15301
15302    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15303        final ActivityRecord TOP_ACT = resumedAppLocked();
15304        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15305        final boolean wasCached = app.cached;
15306
15307        mAdjSeq++;
15308
15309        // This is the desired cached adjusment we want to tell it to use.
15310        // If our app is currently cached, we know it, and that is it.  Otherwise,
15311        // we don't know it yet, and it needs to now be cached we will then
15312        // need to do a complete oom adj.
15313        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15314                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15315        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15316                SystemClock.uptimeMillis());
15317        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15318            // Changed to/from cached state, so apps after it in the LRU
15319            // list may also be changed.
15320            updateOomAdjLocked();
15321        }
15322        return success;
15323    }
15324
15325    final void updateOomAdjLocked() {
15326        final ActivityRecord TOP_ACT = resumedAppLocked();
15327        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15328        final long now = SystemClock.uptimeMillis();
15329        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15330        final int N = mLruProcesses.size();
15331
15332        if (false) {
15333            RuntimeException e = new RuntimeException();
15334            e.fillInStackTrace();
15335            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15336        }
15337
15338        mAdjSeq++;
15339        mNewNumServiceProcs = 0;
15340        mNewNumAServiceProcs = 0;
15341
15342        final int emptyProcessLimit;
15343        final int cachedProcessLimit;
15344        if (mProcessLimit <= 0) {
15345            emptyProcessLimit = cachedProcessLimit = 0;
15346        } else if (mProcessLimit == 1) {
15347            emptyProcessLimit = 1;
15348            cachedProcessLimit = 0;
15349        } else {
15350            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15351            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15352        }
15353
15354        // Let's determine how many processes we have running vs.
15355        // how many slots we have for background processes; we may want
15356        // to put multiple processes in a slot of there are enough of
15357        // them.
15358        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15359                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15360        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15361        if (numEmptyProcs > cachedProcessLimit) {
15362            // If there are more empty processes than our limit on cached
15363            // processes, then use the cached process limit for the factor.
15364            // This ensures that the really old empty processes get pushed
15365            // down to the bottom, so if we are running low on memory we will
15366            // have a better chance at keeping around more cached processes
15367            // instead of a gazillion empty processes.
15368            numEmptyProcs = cachedProcessLimit;
15369        }
15370        int emptyFactor = numEmptyProcs/numSlots;
15371        if (emptyFactor < 1) emptyFactor = 1;
15372        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15373        if (cachedFactor < 1) cachedFactor = 1;
15374        int stepCached = 0;
15375        int stepEmpty = 0;
15376        int numCached = 0;
15377        int numEmpty = 0;
15378        int numTrimming = 0;
15379
15380        mNumNonCachedProcs = 0;
15381        mNumCachedHiddenProcs = 0;
15382
15383        // First update the OOM adjustment for each of the
15384        // application processes based on their current state.
15385        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15386        int nextCachedAdj = curCachedAdj+1;
15387        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15388        int nextEmptyAdj = curEmptyAdj+2;
15389        for (int i=N-1; i>=0; i--) {
15390            ProcessRecord app = mLruProcesses.get(i);
15391            if (!app.killedByAm && app.thread != null) {
15392                app.procStateChanged = false;
15393                final boolean wasKeeping = app.keeping;
15394                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15395
15396                // If we haven't yet assigned the final cached adj
15397                // to the process, do that now.
15398                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15399                    switch (app.curProcState) {
15400                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15401                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15402                            // This process is a cached process holding activities...
15403                            // assign it the next cached value for that type, and then
15404                            // step that cached level.
15405                            app.curRawAdj = curCachedAdj;
15406                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15407                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15408                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15409                                    + ")");
15410                            if (curCachedAdj != nextCachedAdj) {
15411                                stepCached++;
15412                                if (stepCached >= cachedFactor) {
15413                                    stepCached = 0;
15414                                    curCachedAdj = nextCachedAdj;
15415                                    nextCachedAdj += 2;
15416                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15417                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15418                                    }
15419                                }
15420                            }
15421                            break;
15422                        default:
15423                            // For everything else, assign next empty cached process
15424                            // level and bump that up.  Note that this means that
15425                            // long-running services that have dropped down to the
15426                            // cached level will be treated as empty (since their process
15427                            // state is still as a service), which is what we want.
15428                            app.curRawAdj = curEmptyAdj;
15429                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15430                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15431                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15432                                    + ")");
15433                            if (curEmptyAdj != nextEmptyAdj) {
15434                                stepEmpty++;
15435                                if (stepEmpty >= emptyFactor) {
15436                                    stepEmpty = 0;
15437                                    curEmptyAdj = nextEmptyAdj;
15438                                    nextEmptyAdj += 2;
15439                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15440                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15441                                    }
15442                                }
15443                            }
15444                            break;
15445                    }
15446                }
15447
15448                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15449
15450                // Count the number of process types.
15451                switch (app.curProcState) {
15452                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15453                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15454                        mNumCachedHiddenProcs++;
15455                        numCached++;
15456                        if (numCached > cachedProcessLimit) {
15457                            killUnneededProcessLocked(app, "cached #" + numCached);
15458                        }
15459                        break;
15460                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15461                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15462                                && app.lastActivityTime < oldTime) {
15463                            killUnneededProcessLocked(app, "empty for "
15464                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15465                                    / 1000) + "s");
15466                        } else {
15467                            numEmpty++;
15468                            if (numEmpty > emptyProcessLimit) {
15469                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15470                            }
15471                        }
15472                        break;
15473                    default:
15474                        mNumNonCachedProcs++;
15475                        break;
15476                }
15477
15478                if (app.isolated && app.services.size() <= 0) {
15479                    // If this is an isolated process, and there are no
15480                    // services running in it, then the process is no longer
15481                    // needed.  We agressively kill these because we can by
15482                    // definition not re-use the same process again, and it is
15483                    // good to avoid having whatever code was running in them
15484                    // left sitting around after no longer needed.
15485                    killUnneededProcessLocked(app, "isolated not needed");
15486                }
15487
15488                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15489                        && !app.killedByAm) {
15490                    numTrimming++;
15491                }
15492            }
15493        }
15494
15495        mNumServiceProcs = mNewNumServiceProcs;
15496
15497        // Now determine the memory trimming level of background processes.
15498        // Unfortunately we need to start at the back of the list to do this
15499        // properly.  We only do this if the number of background apps we
15500        // are managing to keep around is less than half the maximum we desire;
15501        // if we are keeping a good number around, we'll let them use whatever
15502        // memory they want.
15503        final int numCachedAndEmpty = numCached + numEmpty;
15504        int memFactor;
15505        if (numCached <= ProcessList.TRIM_CACHED_APPS
15506                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15507            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15508                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15509            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15510                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15511            } else {
15512                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15513            }
15514        } else {
15515            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15516        }
15517        // We always allow the memory level to go up (better).  We only allow it to go
15518        // down if we are in a state where that is allowed, *and* the total number of processes
15519        // has gone down since last time.
15520        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15521                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15522                + " last=" + mLastNumProcesses);
15523        if (memFactor > mLastMemoryLevel) {
15524            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15525                memFactor = mLastMemoryLevel;
15526                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15527            }
15528        }
15529        mLastMemoryLevel = memFactor;
15530        mLastNumProcesses = mLruProcesses.size();
15531        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15532        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15533        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15534            if (mLowRamStartTime == 0) {
15535                mLowRamStartTime = now;
15536            }
15537            int step = 0;
15538            int fgTrimLevel;
15539            switch (memFactor) {
15540                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15541                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15542                    break;
15543                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15544                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15545                    break;
15546                default:
15547                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15548                    break;
15549            }
15550            int factor = numTrimming/3;
15551            int minFactor = 2;
15552            if (mHomeProcess != null) minFactor++;
15553            if (mPreviousProcess != null) minFactor++;
15554            if (factor < minFactor) factor = minFactor;
15555            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15556            for (int i=N-1; i>=0; i--) {
15557                ProcessRecord app = mLruProcesses.get(i);
15558                if (allChanged || app.procStateChanged) {
15559                    setProcessTrackerState(app, trackerMemFactor, now);
15560                    app.procStateChanged = false;
15561                }
15562                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15563                        && !app.killedByAm) {
15564                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15565                        try {
15566                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15567                                    "Trimming memory of " + app.processName
15568                                    + " to " + curLevel);
15569                            app.thread.scheduleTrimMemory(curLevel);
15570                        } catch (RemoteException e) {
15571                        }
15572                        if (false) {
15573                            // For now we won't do this; our memory trimming seems
15574                            // to be good enough at this point that destroying
15575                            // activities causes more harm than good.
15576                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15577                                    && app != mHomeProcess && app != mPreviousProcess) {
15578                                // Need to do this on its own message because the stack may not
15579                                // be in a consistent state at this point.
15580                                // For these apps we will also finish their activities
15581                                // to help them free memory.
15582                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15583                            }
15584                        }
15585                    }
15586                    app.trimMemoryLevel = curLevel;
15587                    step++;
15588                    if (step >= factor) {
15589                        step = 0;
15590                        switch (curLevel) {
15591                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15592                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15593                                break;
15594                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15595                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15596                                break;
15597                        }
15598                    }
15599                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15600                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15601                            && app.thread != null) {
15602                        try {
15603                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15604                                    "Trimming memory of heavy-weight " + app.processName
15605                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15606                            app.thread.scheduleTrimMemory(
15607                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15608                        } catch (RemoteException e) {
15609                        }
15610                    }
15611                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15612                } else {
15613                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15614                            || app.systemNoUi) && app.pendingUiClean) {
15615                        // If this application is now in the background and it
15616                        // had done UI, then give it the special trim level to
15617                        // have it free UI resources.
15618                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15619                        if (app.trimMemoryLevel < level && app.thread != null) {
15620                            try {
15621                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15622                                        "Trimming memory of bg-ui " + app.processName
15623                                        + " to " + level);
15624                                app.thread.scheduleTrimMemory(level);
15625                            } catch (RemoteException e) {
15626                            }
15627                        }
15628                        app.pendingUiClean = false;
15629                    }
15630                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15631                        try {
15632                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15633                                    "Trimming memory of fg " + app.processName
15634                                    + " to " + fgTrimLevel);
15635                            app.thread.scheduleTrimMemory(fgTrimLevel);
15636                        } catch (RemoteException e) {
15637                        }
15638                    }
15639                    app.trimMemoryLevel = fgTrimLevel;
15640                }
15641            }
15642        } else {
15643            if (mLowRamStartTime != 0) {
15644                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15645                mLowRamStartTime = 0;
15646            }
15647            for (int i=N-1; i>=0; i--) {
15648                ProcessRecord app = mLruProcesses.get(i);
15649                if (allChanged || app.procStateChanged) {
15650                    setProcessTrackerState(app, trackerMemFactor, now);
15651                    app.procStateChanged = false;
15652                }
15653                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15654                        || app.systemNoUi) && app.pendingUiClean) {
15655                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15656                            && app.thread != null) {
15657                        try {
15658                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15659                                    "Trimming memory of ui hidden " + app.processName
15660                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15661                            app.thread.scheduleTrimMemory(
15662                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15663                        } catch (RemoteException e) {
15664                        }
15665                    }
15666                    app.pendingUiClean = false;
15667                }
15668                app.trimMemoryLevel = 0;
15669            }
15670        }
15671
15672        if (mAlwaysFinishActivities) {
15673            // Need to do this on its own message because the stack may not
15674            // be in a consistent state at this point.
15675            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15676        }
15677
15678        if (allChanged) {
15679            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15680        }
15681
15682        if (mProcessStats.shouldWriteNowLocked(now)) {
15683            mHandler.post(new Runnable() {
15684                @Override public void run() {
15685                    synchronized (ActivityManagerService.this) {
15686                        mProcessStats.writeStateAsyncLocked();
15687                    }
15688                }
15689            });
15690        }
15691
15692        if (DEBUG_OOM_ADJ) {
15693            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15694        }
15695    }
15696
15697    final void trimApplications() {
15698        synchronized (this) {
15699            int i;
15700
15701            // First remove any unused application processes whose package
15702            // has been removed.
15703            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15704                final ProcessRecord app = mRemovedProcesses.get(i);
15705                if (app.activities.size() == 0
15706                        && app.curReceiver == null && app.services.size() == 0) {
15707                    Slog.i(
15708                        TAG, "Exiting empty application process "
15709                        + app.processName + " ("
15710                        + (app.thread != null ? app.thread.asBinder() : null)
15711                        + ")\n");
15712                    if (app.pid > 0 && app.pid != MY_PID) {
15713                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15714                                app.processName, app.setAdj, "empty");
15715                        app.killedByAm = true;
15716                        Process.killProcessQuiet(app.pid);
15717                    } else {
15718                        try {
15719                            app.thread.scheduleExit();
15720                        } catch (Exception e) {
15721                            // Ignore exceptions.
15722                        }
15723                    }
15724                    cleanUpApplicationRecordLocked(app, false, true, -1);
15725                    mRemovedProcesses.remove(i);
15726
15727                    if (app.persistent) {
15728                        if (app.persistent) {
15729                            addAppLocked(app.info, false);
15730                        }
15731                    }
15732                }
15733            }
15734
15735            // Now update the oom adj for all processes.
15736            updateOomAdjLocked();
15737        }
15738    }
15739
15740    /** This method sends the specified signal to each of the persistent apps */
15741    public void signalPersistentProcesses(int sig) throws RemoteException {
15742        if (sig != Process.SIGNAL_USR1) {
15743            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15744        }
15745
15746        synchronized (this) {
15747            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15748                    != PackageManager.PERMISSION_GRANTED) {
15749                throw new SecurityException("Requires permission "
15750                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15751            }
15752
15753            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15754                ProcessRecord r = mLruProcesses.get(i);
15755                if (r.thread != null && r.persistent) {
15756                    Process.sendSignal(r.pid, sig);
15757                }
15758            }
15759        }
15760    }
15761
15762    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15763        if (proc == null || proc == mProfileProc) {
15764            proc = mProfileProc;
15765            path = mProfileFile;
15766            profileType = mProfileType;
15767            clearProfilerLocked();
15768        }
15769        if (proc == null) {
15770            return;
15771        }
15772        try {
15773            proc.thread.profilerControl(false, path, null, profileType);
15774        } catch (RemoteException e) {
15775            throw new IllegalStateException("Process disappeared");
15776        }
15777    }
15778
15779    private void clearProfilerLocked() {
15780        if (mProfileFd != null) {
15781            try {
15782                mProfileFd.close();
15783            } catch (IOException e) {
15784            }
15785        }
15786        mProfileApp = null;
15787        mProfileProc = null;
15788        mProfileFile = null;
15789        mProfileType = 0;
15790        mAutoStopProfiler = false;
15791    }
15792
15793    public boolean profileControl(String process, int userId, boolean start,
15794            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15795
15796        try {
15797            synchronized (this) {
15798                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15799                // its own permission.
15800                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15801                        != PackageManager.PERMISSION_GRANTED) {
15802                    throw new SecurityException("Requires permission "
15803                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15804                }
15805
15806                if (start && fd == null) {
15807                    throw new IllegalArgumentException("null fd");
15808                }
15809
15810                ProcessRecord proc = null;
15811                if (process != null) {
15812                    proc = findProcessLocked(process, userId, "profileControl");
15813                }
15814
15815                if (start && (proc == null || proc.thread == null)) {
15816                    throw new IllegalArgumentException("Unknown process: " + process);
15817                }
15818
15819                if (start) {
15820                    stopProfilerLocked(null, null, 0);
15821                    setProfileApp(proc.info, proc.processName, path, fd, false);
15822                    mProfileProc = proc;
15823                    mProfileType = profileType;
15824                    try {
15825                        fd = fd.dup();
15826                    } catch (IOException e) {
15827                        fd = null;
15828                    }
15829                    proc.thread.profilerControl(start, path, fd, profileType);
15830                    fd = null;
15831                    mProfileFd = null;
15832                } else {
15833                    stopProfilerLocked(proc, path, profileType);
15834                    if (fd != null) {
15835                        try {
15836                            fd.close();
15837                        } catch (IOException e) {
15838                        }
15839                    }
15840                }
15841
15842                return true;
15843            }
15844        } catch (RemoteException e) {
15845            throw new IllegalStateException("Process disappeared");
15846        } finally {
15847            if (fd != null) {
15848                try {
15849                    fd.close();
15850                } catch (IOException e) {
15851                }
15852            }
15853        }
15854    }
15855
15856    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15857        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15858                userId, true, true, callName, null);
15859        ProcessRecord proc = null;
15860        try {
15861            int pid = Integer.parseInt(process);
15862            synchronized (mPidsSelfLocked) {
15863                proc = mPidsSelfLocked.get(pid);
15864            }
15865        } catch (NumberFormatException e) {
15866        }
15867
15868        if (proc == null) {
15869            ArrayMap<String, SparseArray<ProcessRecord>> all
15870                    = mProcessNames.getMap();
15871            SparseArray<ProcessRecord> procs = all.get(process);
15872            if (procs != null && procs.size() > 0) {
15873                proc = procs.valueAt(0);
15874                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15875                    for (int i=1; i<procs.size(); i++) {
15876                        ProcessRecord thisProc = procs.valueAt(i);
15877                        if (thisProc.userId == userId) {
15878                            proc = thisProc;
15879                            break;
15880                        }
15881                    }
15882                }
15883            }
15884        }
15885
15886        return proc;
15887    }
15888
15889    public boolean dumpHeap(String process, int userId, boolean managed,
15890            String path, ParcelFileDescriptor fd) throws RemoteException {
15891
15892        try {
15893            synchronized (this) {
15894                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15895                // its own permission (same as profileControl).
15896                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15897                        != PackageManager.PERMISSION_GRANTED) {
15898                    throw new SecurityException("Requires permission "
15899                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15900                }
15901
15902                if (fd == null) {
15903                    throw new IllegalArgumentException("null fd");
15904                }
15905
15906                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15907                if (proc == null || proc.thread == null) {
15908                    throw new IllegalArgumentException("Unknown process: " + process);
15909                }
15910
15911                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15912                if (!isDebuggable) {
15913                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15914                        throw new SecurityException("Process not debuggable: " + proc);
15915                    }
15916                }
15917
15918                proc.thread.dumpHeap(managed, path, fd);
15919                fd = null;
15920                return true;
15921            }
15922        } catch (RemoteException e) {
15923            throw new IllegalStateException("Process disappeared");
15924        } finally {
15925            if (fd != null) {
15926                try {
15927                    fd.close();
15928                } catch (IOException e) {
15929                }
15930            }
15931        }
15932    }
15933
15934    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15935    public void monitor() {
15936        synchronized (this) { }
15937    }
15938
15939    void onCoreSettingsChange(Bundle settings) {
15940        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15941            ProcessRecord processRecord = mLruProcesses.get(i);
15942            try {
15943                if (processRecord.thread != null) {
15944                    processRecord.thread.setCoreSettings(settings);
15945                }
15946            } catch (RemoteException re) {
15947                /* ignore */
15948            }
15949        }
15950    }
15951
15952    // Multi-user methods
15953
15954    @Override
15955    public boolean switchUser(final int userId) {
15956        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15957                != PackageManager.PERMISSION_GRANTED) {
15958            String msg = "Permission Denial: switchUser() from pid="
15959                    + Binder.getCallingPid()
15960                    + ", uid=" + Binder.getCallingUid()
15961                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15962            Slog.w(TAG, msg);
15963            throw new SecurityException(msg);
15964        }
15965
15966        final long ident = Binder.clearCallingIdentity();
15967        try {
15968            synchronized (this) {
15969                final int oldUserId = mCurrentUserId;
15970                if (oldUserId == userId) {
15971                    return true;
15972                }
15973
15974                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15975                if (userInfo == null) {
15976                    Slog.w(TAG, "No user info for user #" + userId);
15977                    return false;
15978                }
15979
15980                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15981                        R.anim.screen_user_enter);
15982
15983                boolean needStart = false;
15984
15985                // If the user we are switching to is not currently started, then
15986                // we need to start it now.
15987                if (mStartedUsers.get(userId) == null) {
15988                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15989                    updateStartedUserArrayLocked();
15990                    needStart = true;
15991                }
15992
15993                mCurrentUserId = userId;
15994                final Integer userIdInt = Integer.valueOf(userId);
15995                mUserLru.remove(userIdInt);
15996                mUserLru.add(userIdInt);
15997
15998                mWindowManager.setCurrentUser(userId);
15999
16000                // Once the internal notion of the active user has switched, we lock the device
16001                // with the option to show the user switcher on the keyguard.
16002                mWindowManager.lockNow(null);
16003
16004                final UserStartedState uss = mStartedUsers.get(userId);
16005
16006                // Make sure user is in the started state.  If it is currently
16007                // stopping, we need to knock that off.
16008                if (uss.mState == UserStartedState.STATE_STOPPING) {
16009                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16010                    // so we can just fairly silently bring the user back from
16011                    // the almost-dead.
16012                    uss.mState = UserStartedState.STATE_RUNNING;
16013                    updateStartedUserArrayLocked();
16014                    needStart = true;
16015                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16016                    // This means ACTION_SHUTDOWN has been sent, so we will
16017                    // need to treat this as a new boot of the user.
16018                    uss.mState = UserStartedState.STATE_BOOTING;
16019                    updateStartedUserArrayLocked();
16020                    needStart = true;
16021                }
16022
16023                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16024                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16025                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16026                        oldUserId, userId, uss));
16027                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16028                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16029                if (needStart) {
16030                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16031                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16032                            | Intent.FLAG_RECEIVER_FOREGROUND);
16033                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16034                    broadcastIntentLocked(null, null, intent,
16035                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16036                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16037                }
16038
16039                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16040                    if (userId != 0) {
16041                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16042                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16043                        broadcastIntentLocked(null, null, intent, null,
16044                                new IIntentReceiver.Stub() {
16045                                    public void performReceive(Intent intent, int resultCode,
16046                                            String data, Bundle extras, boolean ordered,
16047                                            boolean sticky, int sendingUser) {
16048                                        userInitialized(uss, userId);
16049                                    }
16050                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16051                                true, false, MY_PID, Process.SYSTEM_UID,
16052                                userId);
16053                        uss.initializing = true;
16054                    } else {
16055                        getUserManagerLocked().makeInitialized(userInfo.id);
16056                    }
16057                }
16058
16059                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16060                if (homeInFront) {
16061                    startHomeActivityLocked(userId);
16062                } else {
16063                    mStackSupervisor.resumeTopActivitiesLocked();
16064                }
16065
16066                EventLogTags.writeAmSwitchUser(userId);
16067                getUserManagerLocked().userForeground(userId);
16068                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16069                if (needStart) {
16070                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16071                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16072                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16073                    broadcastIntentLocked(null, null, intent,
16074                            null, new IIntentReceiver.Stub() {
16075                                @Override
16076                                public void performReceive(Intent intent, int resultCode, String data,
16077                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16078                                        throws RemoteException {
16079                                }
16080                            }, 0, null, null,
16081                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16082                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16083                }
16084            }
16085        } finally {
16086            Binder.restoreCallingIdentity(ident);
16087        }
16088
16089        return true;
16090    }
16091
16092    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16093        long ident = Binder.clearCallingIdentity();
16094        try {
16095            Intent intent;
16096            if (oldUserId >= 0) {
16097                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16098                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16099                        | Intent.FLAG_RECEIVER_FOREGROUND);
16100                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16101                broadcastIntentLocked(null, null, intent,
16102                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16103                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16104            }
16105            if (newUserId >= 0) {
16106                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16107                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16108                        | Intent.FLAG_RECEIVER_FOREGROUND);
16109                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16110                broadcastIntentLocked(null, null, intent,
16111                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16112                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16113                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16114                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16115                        | Intent.FLAG_RECEIVER_FOREGROUND);
16116                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16117                broadcastIntentLocked(null, null, intent,
16118                        null, null, 0, null, null,
16119                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16120                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16121            }
16122        } finally {
16123            Binder.restoreCallingIdentity(ident);
16124        }
16125    }
16126
16127    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16128            final int newUserId) {
16129        final int N = mUserSwitchObservers.beginBroadcast();
16130        if (N > 0) {
16131            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16132                int mCount = 0;
16133                @Override
16134                public void sendResult(Bundle data) throws RemoteException {
16135                    synchronized (ActivityManagerService.this) {
16136                        if (mCurUserSwitchCallback == this) {
16137                            mCount++;
16138                            if (mCount == N) {
16139                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16140                            }
16141                        }
16142                    }
16143                }
16144            };
16145            synchronized (this) {
16146                uss.switching = true;
16147                mCurUserSwitchCallback = callback;
16148            }
16149            for (int i=0; i<N; i++) {
16150                try {
16151                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16152                            newUserId, callback);
16153                } catch (RemoteException e) {
16154                }
16155            }
16156        } else {
16157            synchronized (this) {
16158                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16159            }
16160        }
16161        mUserSwitchObservers.finishBroadcast();
16162    }
16163
16164    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16165        synchronized (this) {
16166            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16167            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16168        }
16169    }
16170
16171    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16172        mCurUserSwitchCallback = null;
16173        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16174        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16175                oldUserId, newUserId, uss));
16176    }
16177
16178    void userInitialized(UserStartedState uss, int newUserId) {
16179        completeSwitchAndInitalize(uss, newUserId, true, false);
16180    }
16181
16182    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16183        completeSwitchAndInitalize(uss, newUserId, false, true);
16184    }
16185
16186    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16187            boolean clearInitializing, boolean clearSwitching) {
16188        boolean unfrozen = false;
16189        synchronized (this) {
16190            if (clearInitializing) {
16191                uss.initializing = false;
16192                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16193            }
16194            if (clearSwitching) {
16195                uss.switching = false;
16196            }
16197            if (!uss.switching && !uss.initializing) {
16198                mWindowManager.stopFreezingScreen();
16199                unfrozen = true;
16200            }
16201        }
16202        if (unfrozen) {
16203            final int N = mUserSwitchObservers.beginBroadcast();
16204            for (int i=0; i<N; i++) {
16205                try {
16206                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16207                } catch (RemoteException e) {
16208                }
16209            }
16210            mUserSwitchObservers.finishBroadcast();
16211        }
16212    }
16213
16214    void finishUserSwitch(UserStartedState uss) {
16215        synchronized (this) {
16216            if (uss.mState == UserStartedState.STATE_BOOTING
16217                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16218                uss.mState = UserStartedState.STATE_RUNNING;
16219                final int userId = uss.mHandle.getIdentifier();
16220                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16221                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16222                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16223                broadcastIntentLocked(null, null, intent,
16224                        null, null, 0, null, null,
16225                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16226                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16227            }
16228            int num = mUserLru.size();
16229            int i = 0;
16230            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16231                Integer oldUserId = mUserLru.get(i);
16232                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16233                if (oldUss == null) {
16234                    // Shouldn't happen, but be sane if it does.
16235                    mUserLru.remove(i);
16236                    num--;
16237                    continue;
16238                }
16239                if (oldUss.mState == UserStartedState.STATE_STOPPING
16240                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16241                    // This user is already stopping, doesn't count.
16242                    num--;
16243                    i++;
16244                    continue;
16245                }
16246                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16247                    // Owner and current can't be stopped, but count as running.
16248                    i++;
16249                    continue;
16250                }
16251                // This is a user to be stopped.
16252                stopUserLocked(oldUserId, null);
16253                num--;
16254                i++;
16255            }
16256        }
16257    }
16258
16259    @Override
16260    public int stopUser(final int userId, final IStopUserCallback callback) {
16261        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16262                != PackageManager.PERMISSION_GRANTED) {
16263            String msg = "Permission Denial: switchUser() from pid="
16264                    + Binder.getCallingPid()
16265                    + ", uid=" + Binder.getCallingUid()
16266                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16267            Slog.w(TAG, msg);
16268            throw new SecurityException(msg);
16269        }
16270        if (userId <= 0) {
16271            throw new IllegalArgumentException("Can't stop primary user " + userId);
16272        }
16273        synchronized (this) {
16274            return stopUserLocked(userId, callback);
16275        }
16276    }
16277
16278    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16279        if (mCurrentUserId == userId) {
16280            return ActivityManager.USER_OP_IS_CURRENT;
16281        }
16282
16283        final UserStartedState uss = mStartedUsers.get(userId);
16284        if (uss == null) {
16285            // User is not started, nothing to do...  but we do need to
16286            // callback if requested.
16287            if (callback != null) {
16288                mHandler.post(new Runnable() {
16289                    @Override
16290                    public void run() {
16291                        try {
16292                            callback.userStopped(userId);
16293                        } catch (RemoteException e) {
16294                        }
16295                    }
16296                });
16297            }
16298            return ActivityManager.USER_OP_SUCCESS;
16299        }
16300
16301        if (callback != null) {
16302            uss.mStopCallbacks.add(callback);
16303        }
16304
16305        if (uss.mState != UserStartedState.STATE_STOPPING
16306                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16307            uss.mState = UserStartedState.STATE_STOPPING;
16308            updateStartedUserArrayLocked();
16309
16310            long ident = Binder.clearCallingIdentity();
16311            try {
16312                // We are going to broadcast ACTION_USER_STOPPING and then
16313                // once that is done send a final ACTION_SHUTDOWN and then
16314                // stop the user.
16315                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16316                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16317                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16318                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16319                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16320                // This is the result receiver for the final shutdown broadcast.
16321                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16322                    @Override
16323                    public void performReceive(Intent intent, int resultCode, String data,
16324                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16325                        finishUserStop(uss);
16326                    }
16327                };
16328                // This is the result receiver for the initial stopping broadcast.
16329                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16330                    @Override
16331                    public void performReceive(Intent intent, int resultCode, String data,
16332                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16333                        // On to the next.
16334                        synchronized (ActivityManagerService.this) {
16335                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16336                                // Whoops, we are being started back up.  Abort, abort!
16337                                return;
16338                            }
16339                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16340                        }
16341                        broadcastIntentLocked(null, null, shutdownIntent,
16342                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16343                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16344                    }
16345                };
16346                // Kick things off.
16347                broadcastIntentLocked(null, null, stoppingIntent,
16348                        null, stoppingReceiver, 0, null, null,
16349                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16350                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16351            } finally {
16352                Binder.restoreCallingIdentity(ident);
16353            }
16354        }
16355
16356        return ActivityManager.USER_OP_SUCCESS;
16357    }
16358
16359    void finishUserStop(UserStartedState uss) {
16360        final int userId = uss.mHandle.getIdentifier();
16361        boolean stopped;
16362        ArrayList<IStopUserCallback> callbacks;
16363        synchronized (this) {
16364            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16365            if (mStartedUsers.get(userId) != uss) {
16366                stopped = false;
16367            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16368                stopped = false;
16369            } else {
16370                stopped = true;
16371                // User can no longer run.
16372                mStartedUsers.remove(userId);
16373                mUserLru.remove(Integer.valueOf(userId));
16374                updateStartedUserArrayLocked();
16375
16376                // Clean up all state and processes associated with the user.
16377                // Kill all the processes for the user.
16378                forceStopUserLocked(userId, "finish user");
16379            }
16380        }
16381
16382        for (int i=0; i<callbacks.size(); i++) {
16383            try {
16384                if (stopped) callbacks.get(i).userStopped(userId);
16385                else callbacks.get(i).userStopAborted(userId);
16386            } catch (RemoteException e) {
16387            }
16388        }
16389
16390        mStackSupervisor.removeUserLocked(userId);
16391    }
16392
16393    @Override
16394    public UserInfo getCurrentUser() {
16395        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16396                != PackageManager.PERMISSION_GRANTED) && (
16397                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16398                != PackageManager.PERMISSION_GRANTED)) {
16399            String msg = "Permission Denial: getCurrentUser() from pid="
16400                    + Binder.getCallingPid()
16401                    + ", uid=" + Binder.getCallingUid()
16402                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16403            Slog.w(TAG, msg);
16404            throw new SecurityException(msg);
16405        }
16406        synchronized (this) {
16407            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16408        }
16409    }
16410
16411    int getCurrentUserIdLocked() {
16412        return mCurrentUserId;
16413    }
16414
16415    @Override
16416    public boolean isUserRunning(int userId, boolean orStopped) {
16417        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16418                != PackageManager.PERMISSION_GRANTED) {
16419            String msg = "Permission Denial: isUserRunning() from pid="
16420                    + Binder.getCallingPid()
16421                    + ", uid=" + Binder.getCallingUid()
16422                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16423            Slog.w(TAG, msg);
16424            throw new SecurityException(msg);
16425        }
16426        synchronized (this) {
16427            return isUserRunningLocked(userId, orStopped);
16428        }
16429    }
16430
16431    boolean isUserRunningLocked(int userId, boolean orStopped) {
16432        UserStartedState state = mStartedUsers.get(userId);
16433        if (state == null) {
16434            return false;
16435        }
16436        if (orStopped) {
16437            return true;
16438        }
16439        return state.mState != UserStartedState.STATE_STOPPING
16440                && state.mState != UserStartedState.STATE_SHUTDOWN;
16441    }
16442
16443    @Override
16444    public int[] getRunningUserIds() {
16445        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16446                != PackageManager.PERMISSION_GRANTED) {
16447            String msg = "Permission Denial: isUserRunning() from pid="
16448                    + Binder.getCallingPid()
16449                    + ", uid=" + Binder.getCallingUid()
16450                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16451            Slog.w(TAG, msg);
16452            throw new SecurityException(msg);
16453        }
16454        synchronized (this) {
16455            return mStartedUserArray;
16456        }
16457    }
16458
16459    private void updateStartedUserArrayLocked() {
16460        int num = 0;
16461        for (int i=0; i<mStartedUsers.size();  i++) {
16462            UserStartedState uss = mStartedUsers.valueAt(i);
16463            // This list does not include stopping users.
16464            if (uss.mState != UserStartedState.STATE_STOPPING
16465                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16466                num++;
16467            }
16468        }
16469        mStartedUserArray = new int[num];
16470        num = 0;
16471        for (int i=0; i<mStartedUsers.size();  i++) {
16472            UserStartedState uss = mStartedUsers.valueAt(i);
16473            if (uss.mState != UserStartedState.STATE_STOPPING
16474                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16475                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16476                num++;
16477            }
16478        }
16479    }
16480
16481    @Override
16482    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16483        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16484                != PackageManager.PERMISSION_GRANTED) {
16485            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16486                    + Binder.getCallingPid()
16487                    + ", uid=" + Binder.getCallingUid()
16488                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16489            Slog.w(TAG, msg);
16490            throw new SecurityException(msg);
16491        }
16492
16493        mUserSwitchObservers.register(observer);
16494    }
16495
16496    @Override
16497    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16498        mUserSwitchObservers.unregister(observer);
16499    }
16500
16501    private boolean userExists(int userId) {
16502        if (userId == 0) {
16503            return true;
16504        }
16505        UserManagerService ums = getUserManagerLocked();
16506        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16507    }
16508
16509    int[] getUsersLocked() {
16510        UserManagerService ums = getUserManagerLocked();
16511        return ums != null ? ums.getUserIds() : new int[] { 0 };
16512    }
16513
16514    UserManagerService getUserManagerLocked() {
16515        if (mUserManager == null) {
16516            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16517            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16518        }
16519        return mUserManager;
16520    }
16521
16522    private int applyUserId(int uid, int userId) {
16523        return UserHandle.getUid(userId, uid);
16524    }
16525
16526    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16527        if (info == null) return null;
16528        ApplicationInfo newInfo = new ApplicationInfo(info);
16529        newInfo.uid = applyUserId(info.uid, userId);
16530        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16531                + info.packageName;
16532        return newInfo;
16533    }
16534
16535    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16536        if (aInfo == null
16537                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16538            return aInfo;
16539        }
16540
16541        ActivityInfo info = new ActivityInfo(aInfo);
16542        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16543        return info;
16544    }
16545}
16546