ActivityManagerService.java revision 9158825f9c41869689d6b1786d7c7aa8bdd524ce
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.util.ArrayMap;
36import com.android.internal.R;
37import com.android.internal.annotations.GuardedBy;
38import com.android.internal.app.IAppOpsService;
39import com.android.internal.app.ProcessMap;
40import com.android.internal.app.ProcessStats;
41import com.android.internal.os.BackgroundThread;
42import com.android.internal.os.BatteryStatsImpl;
43import com.android.internal.os.ProcessCpuTracker;
44import com.android.internal.os.TransferPipe;
45import com.android.internal.util.FastPrintWriter;
46import com.android.internal.util.FastXmlSerializer;
47import com.android.internal.util.MemInfoReader;
48import com.android.internal.util.Preconditions;
49import com.android.server.AppOpsService;
50import com.android.server.AttributeCache;
51import com.android.server.IntentResolver;
52import com.android.server.SystemServer;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.UserManagerService;
57import com.android.server.wm.AppTransition;
58import com.android.server.wm.WindowManagerService;
59import com.google.android.collect.Lists;
60import com.google.android.collect.Maps;
61
62import dalvik.system.Zygote;
63
64import libcore.io.IoUtils;
65
66import org.xmlpull.v1.XmlPullParser;
67import org.xmlpull.v1.XmlPullParserException;
68import org.xmlpull.v1.XmlSerializer;
69
70import android.app.Activity;
71import android.app.ActivityManager;
72import android.app.ActivityManager.RunningTaskInfo;
73import android.app.ActivityManager.StackInfo;
74import android.app.ActivityManagerNative;
75import android.app.ActivityOptions;
76import android.app.ActivityThread;
77import android.app.AlertDialog;
78import android.app.AppGlobals;
79import android.app.ApplicationErrorReport;
80import android.app.Dialog;
81import android.app.IActivityController;
82import android.app.IApplicationThread;
83import android.app.IInstrumentationWatcher;
84import android.app.INotificationManager;
85import android.app.IProcessObserver;
86import android.app.IServiceConnection;
87import android.app.IStopUserCallback;
88import android.app.IThumbnailReceiver;
89import android.app.IUiAutomationConnection;
90import android.app.IUserSwitchObserver;
91import android.app.Instrumentation;
92import android.app.Notification;
93import android.app.NotificationManager;
94import android.app.PendingIntent;
95import android.app.backup.IBackupManager;
96import android.content.ActivityNotFoundException;
97import android.content.BroadcastReceiver;
98import android.content.ClipData;
99import android.content.ComponentCallbacks2;
100import android.content.ComponentName;
101import android.content.ContentProvider;
102import android.content.ContentResolver;
103import android.content.Context;
104import android.content.DialogInterface;
105import android.content.IContentProvider;
106import android.content.IIntentReceiver;
107import android.content.IIntentSender;
108import android.content.Intent;
109import android.content.IntentFilter;
110import android.content.IntentSender;
111import android.content.pm.ActivityInfo;
112import android.content.pm.ApplicationInfo;
113import android.content.pm.ConfigurationInfo;
114import android.content.pm.IPackageDataObserver;
115import android.content.pm.IPackageManager;
116import android.content.pm.InstrumentationInfo;
117import android.content.pm.PackageInfo;
118import android.content.pm.PackageManager;
119import android.content.pm.ParceledListSlice;
120import android.content.pm.UserInfo;
121import android.content.pm.PackageManager.NameNotFoundException;
122import android.content.pm.PathPermission;
123import android.content.pm.ProviderInfo;
124import android.content.pm.ResolveInfo;
125import android.content.pm.ServiceInfo;
126import android.content.res.CompatibilityInfo;
127import android.content.res.Configuration;
128import android.graphics.Bitmap;
129import android.net.Proxy;
130import android.net.ProxyProperties;
131import android.net.Uri;
132import android.os.Binder;
133import android.os.Build;
134import android.os.Bundle;
135import android.os.Debug;
136import android.os.DropBoxManager;
137import android.os.Environment;
138import android.os.FileObserver;
139import android.os.FileUtils;
140import android.os.Handler;
141import android.os.IBinder;
142import android.os.IPermissionController;
143import android.os.IRemoteCallback;
144import android.os.IUserManager;
145import android.os.Looper;
146import android.os.Message;
147import android.os.Parcel;
148import android.os.ParcelFileDescriptor;
149import android.os.Process;
150import android.os.RemoteCallbackList;
151import android.os.RemoteException;
152import android.os.SELinux;
153import android.os.ServiceManager;
154import android.os.StrictMode;
155import android.os.SystemClock;
156import android.os.SystemProperties;
157import android.os.UpdateLock;
158import android.os.UserHandle;
159import android.provider.Settings;
160import android.text.format.DateUtils;
161import android.text.format.Time;
162import android.util.AtomicFile;
163import android.util.EventLog;
164import android.util.Log;
165import android.util.Pair;
166import android.util.PrintWriterPrinter;
167import android.util.Slog;
168import android.util.SparseArray;
169import android.util.TimeUtils;
170import android.util.Xml;
171import android.view.Gravity;
172import android.view.LayoutInflater;
173import android.view.View;
174import android.view.WindowManager;
175
176import java.io.BufferedInputStream;
177import java.io.BufferedOutputStream;
178import java.io.DataInputStream;
179import java.io.DataOutputStream;
180import java.io.File;
181import java.io.FileDescriptor;
182import java.io.FileInputStream;
183import java.io.FileNotFoundException;
184import java.io.FileOutputStream;
185import java.io.IOException;
186import java.io.InputStreamReader;
187import java.io.PrintWriter;
188import java.io.StringWriter;
189import java.lang.ref.WeakReference;
190import java.util.ArrayList;
191import java.util.Arrays;
192import java.util.Collections;
193import java.util.Comparator;
194import java.util.HashMap;
195import java.util.HashSet;
196import java.util.Iterator;
197import java.util.List;
198import java.util.Locale;
199import java.util.Map;
200import java.util.Set;
201import java.util.concurrent.atomic.AtomicBoolean;
202import java.util.concurrent.atomic.AtomicLong;
203
204public final class ActivityManagerService extends ActivityManagerNative
205        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
206    private static final String USER_DATA_DIR = "/data/user/";
207    static final String TAG = "ActivityManager";
208    static final String TAG_MU = "ActivityManagerServiceMU";
209    static final boolean DEBUG = false;
210    static final boolean localLOGV = DEBUG;
211    static final boolean DEBUG_BACKUP = localLOGV || false;
212    static final boolean DEBUG_BROADCAST = localLOGV || false;
213    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
214    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
215    static final boolean DEBUG_CLEANUP = localLOGV || false;
216    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
217    static final boolean DEBUG_FOCUS = false;
218    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
219    static final boolean DEBUG_MU = localLOGV || false;
220    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
221    static final boolean DEBUG_LRU = localLOGV || false;
222    static final boolean DEBUG_PAUSE = localLOGV || false;
223    static final boolean DEBUG_POWER = localLOGV || false;
224    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
225    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
226    static final boolean DEBUG_PROCESSES = localLOGV || false;
227    static final boolean DEBUG_PROVIDER = localLOGV || false;
228    static final boolean DEBUG_RESULTS = localLOGV || false;
229    static final boolean DEBUG_SERVICE = localLOGV || false;
230    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
231    static final boolean DEBUG_STACK = localLOGV || false;
232    static final boolean DEBUG_SWITCH = localLOGV || false;
233    static final boolean DEBUG_TASKS = localLOGV || false;
234    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
235    static final boolean DEBUG_TRANSITION = localLOGV || false;
236    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
237    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
238    static final boolean DEBUG_VISBILITY = localLOGV || false;
239    static final boolean DEBUG_PSS = localLOGV || false;
240    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
241    static final boolean VALIDATE_TOKENS = false;
242    static final boolean SHOW_ACTIVITY_START_TIME = true;
243
244    // Control over CPU and battery monitoring.
245    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
246    static final boolean MONITOR_CPU_USAGE = true;
247    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
248    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
249    static final boolean MONITOR_THREAD_CPU_USAGE = false;
250
251    // The flags that are set for all calls we make to the package manager.
252    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
253
254    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
255
256    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
257
258    // Maximum number of recent tasks that we can remember.
259    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
260
261    // Amount of time after a call to stopAppSwitches() during which we will
262    // prevent further untrusted switches from happening.
263    static final long APP_SWITCH_DELAY_TIME = 5*1000;
264
265    // How long we wait for a launched process to attach to the activity manager
266    // before we decide it's never going to come up for real.
267    static final int PROC_START_TIMEOUT = 10*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, when the process was
271    // started with a wrapper for instrumentation (such as Valgrind) because it
272    // could take much longer than usual.
273    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
274
275    // How long to wait after going idle before forcing apps to GC.
276    static final int GC_TIMEOUT = 5*1000;
277
278    // The minimum amount of time between successive GC requests for a process.
279    static final int GC_MIN_INTERVAL = 60*1000;
280
281    // The minimum amount of time between successive PSS requests for a process.
282    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process
285    // when the request is due to the memory state being lowered.
286    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
287
288    // The rate at which we check for apps using excessive power -- 15 mins.
289    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
290
291    // The minimum sample duration we will allow before deciding we have
292    // enough data on wake locks to start killing things.
293    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
294
295    // The minimum sample duration we will allow before deciding we have
296    // enough data on CPU usage to start killing things.
297    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
298
299    // How long we allow a receiver to run before giving up on it.
300    static final int BROADCAST_FG_TIMEOUT = 10*1000;
301    static final int BROADCAST_BG_TIMEOUT = 60*1000;
302
303    // How long we wait until we timeout on key dispatching.
304    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
305
306    // How long we wait until we timeout on key dispatching during instrumentation.
307    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
308
309    // Amount of time we wait for observers to handle a user switch before
310    // giving up on them and unfreezing the screen.
311    static final int USER_SWITCH_TIMEOUT = 2*1000;
312
313    // Maximum number of users we allow to be running at a time.
314    static final int MAX_RUNNING_USERS = 3;
315
316    // How long to wait in getAssistContextExtras for the activity and foreground services
317    // to respond with the result.
318    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
319
320    // Maximum number of persisted Uri grants a package is allowed
321    static final int MAX_PERSISTED_URI_GRANTS = 128;
322
323    static final int MY_PID = Process.myPid();
324
325    static final String[] EMPTY_STRING_ARRAY = new String[0];
326
327    // How many bytes to write into the dropbox log before truncating
328    static final int DROPBOX_MAX_SIZE = 256 * 1024;
329
330    /** Run all ActivityStacks through this */
331    ActivityStackSupervisor mStackSupervisor;
332
333    public IntentFirewall mIntentFirewall;
334
335    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
336    // default actuion automatically.  Important for devices without direct input
337    // devices.
338    private boolean mShowDialogs = true;
339
340    /**
341     * Description of a request to start a new activity, which has been held
342     * due to app switches being disabled.
343     */
344    static class PendingActivityLaunch {
345        final ActivityRecord r;
346        final ActivityRecord sourceRecord;
347        final int startFlags;
348        final ActivityStack stack;
349
350        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
351                int _startFlags, ActivityStack _stack) {
352            r = _r;
353            sourceRecord = _sourceRecord;
354            startFlags = _startFlags;
355            stack = _stack;
356        }
357    }
358
359    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
360            = new ArrayList<PendingActivityLaunch>();
361
362    BroadcastQueue mFgBroadcastQueue;
363    BroadcastQueue mBgBroadcastQueue;
364    // Convenient for easy iteration over the queues. Foreground is first
365    // so that dispatch of foreground broadcasts gets precedence.
366    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
367
368    BroadcastQueue broadcastQueueForIntent(Intent intent) {
369        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
370        if (DEBUG_BACKGROUND_BROADCAST) {
371            Slog.i(TAG, "Broadcast intent " + intent + " on "
372                    + (isFg ? "foreground" : "background")
373                    + " queue");
374        }
375        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
376    }
377
378    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
379        for (BroadcastQueue queue : mBroadcastQueues) {
380            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
381            if (r != null) {
382                return r;
383            }
384        }
385        return null;
386    }
387
388    /**
389     * Activity we have told the window manager to have key focus.
390     */
391    ActivityRecord mFocusedActivity = null;
392
393    /**
394     * List of intents that were used to start the most recent tasks.
395     */
396    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
397
398    public class PendingAssistExtras extends Binder implements Runnable {
399        public final ActivityRecord activity;
400        public boolean haveResult = false;
401        public Bundle result = null;
402        public PendingAssistExtras(ActivityRecord _activity) {
403            activity = _activity;
404        }
405        @Override
406        public void run() {
407            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
408            synchronized (this) {
409                haveResult = true;
410                notifyAll();
411            }
412        }
413    }
414
415    final ArrayList<PendingAssistExtras> mPendingAssistExtras
416            = new ArrayList<PendingAssistExtras>();
417
418    /**
419     * Process management.
420     */
421    final ProcessList mProcessList = new ProcessList();
422
423    /**
424     * All of the applications we currently have running organized by name.
425     * The keys are strings of the application package name (as
426     * returned by the package manager), and the keys are ApplicationRecord
427     * objects.
428     */
429    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
430
431    /**
432     * Tracking long-term execution of processes to look for abuse and other
433     * bad app behavior.
434     */
435    final ProcessStatsService mProcessStats;
436
437    /**
438     * The currently running isolated processes.
439     */
440    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
441
442    /**
443     * Counter for assigning isolated process uids, to avoid frequently reusing the
444     * same ones.
445     */
446    int mNextIsolatedProcessUid = 0;
447
448    /**
449     * The currently running heavy-weight process, if any.
450     */
451    ProcessRecord mHeavyWeightProcess = null;
452
453    /**
454     * The last time that various processes have crashed.
455     */
456    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
457
458    /**
459     * Information about a process that is currently marked as bad.
460     */
461    static final class BadProcessInfo {
462        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
463            this.time = time;
464            this.shortMsg = shortMsg;
465            this.longMsg = longMsg;
466            this.stack = stack;
467        }
468
469        final long time;
470        final String shortMsg;
471        final String longMsg;
472        final String stack;
473    }
474
475    /**
476     * Set of applications that we consider to be bad, and will reject
477     * incoming broadcasts from (which the user has no control over).
478     * Processes are added to this set when they have crashed twice within
479     * a minimum amount of time; they are removed from it when they are
480     * later restarted (hopefully due to some user action).  The value is the
481     * time it was added to the list.
482     */
483    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
484
485    /**
486     * All of the processes we currently have running organized by pid.
487     * The keys are the pid running the application.
488     *
489     * <p>NOTE: This object is protected by its own lock, NOT the global
490     * activity manager lock!
491     */
492    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
493
494    /**
495     * All of the processes that have been forced to be foreground.  The key
496     * is the pid of the caller who requested it (we hold a death
497     * link on it).
498     */
499    abstract class ForegroundToken implements IBinder.DeathRecipient {
500        int pid;
501        IBinder token;
502    }
503    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
504
505    /**
506     * List of records for processes that someone had tried to start before the
507     * system was ready.  We don't start them at that point, but ensure they
508     * are started by the time booting is complete.
509     */
510    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
511
512    /**
513     * List of persistent applications that are in the process
514     * of being started.
515     */
516    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
517
518    /**
519     * Processes that are being forcibly torn down.
520     */
521    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
522
523    /**
524     * List of running applications, sorted by recent usage.
525     * The first entry in the list is the least recently used.
526     */
527    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
528
529    /**
530     * Where in mLruProcesses that the processes hosting activities start.
531     */
532    int mLruProcessActivityStart = 0;
533
534    /**
535     * Where in mLruProcesses that the processes hosting services start.
536     * This is after (lower index) than mLruProcessesActivityStart.
537     */
538    int mLruProcessServiceStart = 0;
539
540    /**
541     * List of processes that should gc as soon as things are idle.
542     */
543    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
544
545    /**
546     * Processes we want to collect PSS data from.
547     */
548    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
549
550    /**
551     * Last time we requested PSS data of all processes.
552     */
553    long mLastFullPssTime = SystemClock.uptimeMillis();
554
555    /**
556     * This is the process holding what we currently consider to be
557     * the "home" activity.
558     */
559    ProcessRecord mHomeProcess;
560
561    /**
562     * This is the process holding the activity the user last visited that
563     * is in a different process from the one they are currently in.
564     */
565    ProcessRecord mPreviousProcess;
566
567    /**
568     * The time at which the previous process was last visible.
569     */
570    long mPreviousProcessVisibleTime;
571
572    /**
573     * Which uses have been started, so are allowed to run code.
574     */
575    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
576
577    /**
578     * LRU list of history of current users.  Most recently current is at the end.
579     */
580    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
581
582    /**
583     * Constant array of the users that are currently started.
584     */
585    int[] mStartedUserArray = new int[] { 0 };
586
587    /**
588     * Registered observers of the user switching mechanics.
589     */
590    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
591            = new RemoteCallbackList<IUserSwitchObserver>();
592
593    /**
594     * Currently active user switch.
595     */
596    Object mCurUserSwitchCallback;
597
598    /**
599     * Packages that the user has asked to have run in screen size
600     * compatibility mode instead of filling the screen.
601     */
602    final CompatModePackages mCompatModePackages;
603
604    /**
605     * Set of IntentSenderRecord objects that are currently active.
606     */
607    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
608            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
609
610    /**
611     * Fingerprints (hashCode()) of stack traces that we've
612     * already logged DropBox entries for.  Guarded by itself.  If
613     * something (rogue user app) forces this over
614     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
615     */
616    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
617    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
618
619    /**
620     * Strict Mode background batched logging state.
621     *
622     * The string buffer is guarded by itself, and its lock is also
623     * used to determine if another batched write is already
624     * in-flight.
625     */
626    private final StringBuilder mStrictModeBuffer = new StringBuilder();
627
628    /**
629     * Keeps track of all IIntentReceivers that have been registered for
630     * broadcasts.  Hash keys are the receiver IBinder, hash value is
631     * a ReceiverList.
632     */
633    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
634            new HashMap<IBinder, ReceiverList>();
635
636    /**
637     * Resolver for broadcast intents to registered receivers.
638     * Holds BroadcastFilter (subclass of IntentFilter).
639     */
640    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
641            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
642        @Override
643        protected boolean allowFilterResult(
644                BroadcastFilter filter, List<BroadcastFilter> dest) {
645            IBinder target = filter.receiverList.receiver.asBinder();
646            for (int i=dest.size()-1; i>=0; i--) {
647                if (dest.get(i).receiverList.receiver.asBinder() == target) {
648                    return false;
649                }
650            }
651            return true;
652        }
653
654        @Override
655        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
656            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
657                    || userId == filter.owningUserId) {
658                return super.newResult(filter, match, userId);
659            }
660            return null;
661        }
662
663        @Override
664        protected BroadcastFilter[] newArray(int size) {
665            return new BroadcastFilter[size];
666        }
667
668        @Override
669        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
670            return packageName.equals(filter.packageName);
671        }
672    };
673
674    /**
675     * State of all active sticky broadcasts per user.  Keys are the action of the
676     * sticky Intent, values are an ArrayList of all broadcasted intents with
677     * that action (which should usually be one).  The SparseArray is keyed
678     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
679     * for stickies that are sent to all users.
680     */
681    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
682            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
683
684    final ActiveServices mServices;
685
686    /**
687     * Backup/restore process management
688     */
689    String mBackupAppName = null;
690    BackupRecord mBackupTarget = null;
691
692    /**
693     * List of PendingThumbnailsRecord objects of clients who are still
694     * waiting to receive all of the thumbnails for a task.
695     */
696    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
697            new ArrayList<PendingThumbnailsRecord>();
698
699    final ProviderMap mProviderMap;
700
701    /**
702     * List of content providers who have clients waiting for them.  The
703     * application is currently being launched and the provider will be
704     * removed from this list once it is published.
705     */
706    final ArrayList<ContentProviderRecord> mLaunchingProviders
707            = new ArrayList<ContentProviderRecord>();
708
709    /**
710     * File storing persisted {@link #mGrantedUriPermissions}.
711     */
712    private final AtomicFile mGrantFile;
713
714    /** XML constants used in {@link #mGrantFile} */
715    private static final String TAG_URI_GRANTS = "uri-grants";
716    private static final String TAG_URI_GRANT = "uri-grant";
717    private static final String ATTR_USER_HANDLE = "userHandle";
718    private static final String ATTR_SOURCE_PKG = "sourcePkg";
719    private static final String ATTR_TARGET_PKG = "targetPkg";
720    private static final String ATTR_URI = "uri";
721    private static final String ATTR_MODE_FLAGS = "modeFlags";
722    private static final String ATTR_CREATED_TIME = "createdTime";
723
724    /**
725     * Global set of specific {@link Uri} permissions that have been granted.
726     * This optimized lookup structure maps from {@link UriPermission#targetUid}
727     * to {@link UriPermission#uri} to {@link UriPermission}.
728     */
729    @GuardedBy("this")
730    private final SparseArray<ArrayMap<Uri, UriPermission>>
731            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
732
733    CoreSettingsObserver mCoreSettingsObserver;
734
735    /**
736     * Thread-local storage used to carry caller permissions over through
737     * indirect content-provider access.
738     */
739    private class Identity {
740        public int pid;
741        public int uid;
742
743        Identity(int _pid, int _uid) {
744            pid = _pid;
745            uid = _uid;
746        }
747    }
748
749    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
750
751    /**
752     * All information we have collected about the runtime performance of
753     * any user id that can impact battery performance.
754     */
755    final BatteryStatsService mBatteryStatsService;
756
757    /**
758     * Information about component usage
759     */
760    final UsageStatsService mUsageStatsService;
761
762    /**
763     * Information about and control over application operations
764     */
765    final AppOpsService mAppOpsService;
766
767    /**
768     * Current configuration information.  HistoryRecord objects are given
769     * a reference to this object to indicate which configuration they are
770     * currently running in, so this object must be kept immutable.
771     */
772    Configuration mConfiguration = new Configuration();
773
774    /**
775     * Current sequencing integer of the configuration, for skipping old
776     * configurations.
777     */
778    int mConfigurationSeq = 0;
779
780    /**
781     * Hardware-reported OpenGLES version.
782     */
783    final int GL_ES_VERSION;
784
785    /**
786     * List of initialization arguments to pass to all processes when binding applications to them.
787     * For example, references to the commonly used services.
788     */
789    HashMap<String, IBinder> mAppBindArgs;
790
791    /**
792     * Temporary to avoid allocations.  Protected by main lock.
793     */
794    final StringBuilder mStringBuilder = new StringBuilder(256);
795
796    /**
797     * Used to control how we initialize the service.
798     */
799    boolean mStartRunning = false;
800    ComponentName mTopComponent;
801    String mTopAction;
802    String mTopData;
803    boolean mProcessesReady = false;
804    boolean mSystemReady = false;
805    boolean mBooting = false;
806    boolean mWaitingUpdate = false;
807    boolean mDidUpdate = false;
808    boolean mOnBattery = false;
809    boolean mLaunchWarningShown = false;
810
811    Context mContext;
812
813    int mFactoryTest;
814
815    boolean mCheckedForSetup;
816
817    /**
818     * The time at which we will allow normal application switches again,
819     * after a call to {@link #stopAppSwitches()}.
820     */
821    long mAppSwitchesAllowedTime;
822
823    /**
824     * This is set to true after the first switch after mAppSwitchesAllowedTime
825     * is set; any switches after that will clear the time.
826     */
827    boolean mDidAppSwitch;
828
829    /**
830     * Last time (in realtime) at which we checked for power usage.
831     */
832    long mLastPowerCheckRealtime;
833
834    /**
835     * Last time (in uptime) at which we checked for power usage.
836     */
837    long mLastPowerCheckUptime;
838
839    /**
840     * Set while we are wanting to sleep, to prevent any
841     * activities from being started/resumed.
842     */
843    boolean mSleeping = false;
844
845    /**
846     * State of external calls telling us if the device is asleep.
847     */
848    boolean mWentToSleep = false;
849
850    /**
851     * State of external call telling us if the lock screen is shown.
852     */
853    boolean mLockScreenShown = false;
854
855    /**
856     * Set if we are shutting down the system, similar to sleeping.
857     */
858    boolean mShuttingDown = false;
859
860    /**
861     * Current sequence id for oom_adj computation traversal.
862     */
863    int mAdjSeq = 0;
864
865    /**
866     * Current sequence id for process LRU updating.
867     */
868    int mLruSeq = 0;
869
870    /**
871     * Keep track of the non-cached/empty process we last found, to help
872     * determine how to distribute cached/empty processes next time.
873     */
874    int mNumNonCachedProcs = 0;
875
876    /**
877     * Keep track of the number of cached hidden procs, to balance oom adj
878     * distribution between those and empty procs.
879     */
880    int mNumCachedHiddenProcs = 0;
881
882    /**
883     * Keep track of the number of service processes we last found, to
884     * determine on the next iteration which should be B services.
885     */
886    int mNumServiceProcs = 0;
887    int mNewNumAServiceProcs = 0;
888    int mNewNumServiceProcs = 0;
889
890    /**
891     * Allow the current computed overall memory level of the system to go down?
892     * This is set to false when we are killing processes for reasons other than
893     * memory management, so that the now smaller process list will not be taken as
894     * an indication that memory is tighter.
895     */
896    boolean mAllowLowerMemLevel = false;
897
898    /**
899     * The last computed memory level, for holding when we are in a state that
900     * processes are going away for other reasons.
901     */
902    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
903
904    /**
905     * The last total number of process we have, to determine if changes actually look
906     * like a shrinking number of process due to lower RAM.
907     */
908    int mLastNumProcesses;
909
910    /**
911     * The uptime of the last time we performed idle maintenance.
912     */
913    long mLastIdleTime = SystemClock.uptimeMillis();
914
915    /**
916     * Total time spent with RAM that has been added in the past since the last idle time.
917     */
918    long mLowRamTimeSinceLastIdle = 0;
919
920    /**
921     * If RAM is currently low, when that horrible situatin started.
922     */
923    long mLowRamStartTime = 0;
924
925    /**
926     * This is set if we had to do a delayed dexopt of an app before launching
927     * it, to increasing the ANR timeouts in that case.
928     */
929    boolean mDidDexOpt;
930
931    String mDebugApp = null;
932    boolean mWaitForDebugger = false;
933    boolean mDebugTransient = false;
934    String mOrigDebugApp = null;
935    boolean mOrigWaitForDebugger = false;
936    boolean mAlwaysFinishActivities = false;
937    IActivityController mController = null;
938    String mProfileApp = null;
939    ProcessRecord mProfileProc = null;
940    String mProfileFile;
941    ParcelFileDescriptor mProfileFd;
942    int mProfileType = 0;
943    boolean mAutoStopProfiler = false;
944    String mOpenGlTraceApp = null;
945
946    static class ProcessChangeItem {
947        static final int CHANGE_ACTIVITIES = 1<<0;
948        static final int CHANGE_IMPORTANCE= 1<<1;
949        int changes;
950        int uid;
951        int pid;
952        int importance;
953        boolean foregroundActivities;
954    }
955
956    final RemoteCallbackList<IProcessObserver> mProcessObservers
957            = new RemoteCallbackList<IProcessObserver>();
958    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
959
960    final ArrayList<ProcessChangeItem> mPendingProcessChanges
961            = new ArrayList<ProcessChangeItem>();
962    final ArrayList<ProcessChangeItem> mAvailProcessChanges
963            = new ArrayList<ProcessChangeItem>();
964
965    /**
966     * Runtime CPU use collection thread.  This object's lock is used to
967     * protect all related state.
968     */
969    final Thread mProcessCpuThread;
970
971    /**
972     * Used to collect process stats when showing not responding dialog.
973     * Protected by mProcessCpuThread.
974     */
975    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
976            MONITOR_THREAD_CPU_USAGE);
977    final AtomicLong mLastCpuTime = new AtomicLong(0);
978    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
979
980    long mLastWriteTime = 0;
981
982    /**
983     * Used to retain an update lock when the foreground activity is in
984     * immersive mode.
985     */
986    final UpdateLock mUpdateLock = new UpdateLock("immersive");
987
988    /**
989     * Set to true after the system has finished booting.
990     */
991    boolean mBooted = false;
992
993    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
994    int mProcessLimitOverride = -1;
995
996    WindowManagerService mWindowManager;
997
998    static ActivityManagerService mSelf;
999    static ActivityThread mSystemThread;
1000
1001    int mCurrentUserId = 0;
1002    private UserManagerService mUserManager;
1003
1004    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1005        final ProcessRecord mApp;
1006        final int mPid;
1007        final IApplicationThread mAppThread;
1008
1009        AppDeathRecipient(ProcessRecord app, int pid,
1010                IApplicationThread thread) {
1011            if (localLOGV) Slog.v(
1012                TAG, "New death recipient " + this
1013                + " for thread " + thread.asBinder());
1014            mApp = app;
1015            mPid = pid;
1016            mAppThread = thread;
1017        }
1018
1019        @Override
1020        public void binderDied() {
1021            if (localLOGV) Slog.v(
1022                TAG, "Death received in " + this
1023                + " for thread " + mAppThread.asBinder());
1024            synchronized(ActivityManagerService.this) {
1025                appDiedLocked(mApp, mPid, mAppThread);
1026            }
1027        }
1028    }
1029
1030    static final int SHOW_ERROR_MSG = 1;
1031    static final int SHOW_NOT_RESPONDING_MSG = 2;
1032    static final int SHOW_FACTORY_ERROR_MSG = 3;
1033    static final int UPDATE_CONFIGURATION_MSG = 4;
1034    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1035    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1036    static final int SERVICE_TIMEOUT_MSG = 12;
1037    static final int UPDATE_TIME_ZONE = 13;
1038    static final int SHOW_UID_ERROR_MSG = 14;
1039    static final int IM_FEELING_LUCKY_MSG = 15;
1040    static final int PROC_START_TIMEOUT_MSG = 20;
1041    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1042    static final int KILL_APPLICATION_MSG = 22;
1043    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1044    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1045    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1046    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1047    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1048    static final int CLEAR_DNS_CACHE_MSG = 28;
1049    static final int UPDATE_HTTP_PROXY_MSG = 29;
1050    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1051    static final int DISPATCH_PROCESSES_CHANGED = 31;
1052    static final int DISPATCH_PROCESS_DIED = 32;
1053    static final int REPORT_MEM_USAGE_MSG = 33;
1054    static final int REPORT_USER_SWITCH_MSG = 34;
1055    static final int CONTINUE_USER_SWITCH_MSG = 35;
1056    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1057    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1058    static final int PERSIST_URI_GRANTS_MSG = 38;
1059    static final int REQUEST_ALL_PSS_MSG = 39;
1060
1061    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1062    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1063    static final int FIRST_COMPAT_MODE_MSG = 300;
1064    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1065
1066    AlertDialog mUidAlert;
1067    CompatModeDialog mCompatModeDialog;
1068    long mLastMemUsageReportTime = 0;
1069
1070    /**
1071     * Flag whether the current user is a "monkey", i.e. whether
1072     * the UI is driven by a UI automation tool.
1073     */
1074    private boolean mUserIsMonkey;
1075
1076    final Handler mHandler = new Handler() {
1077        //public Handler() {
1078        //    if (localLOGV) Slog.v(TAG, "Handler started!");
1079        //}
1080
1081        @Override
1082        public void handleMessage(Message msg) {
1083            switch (msg.what) {
1084            case SHOW_ERROR_MSG: {
1085                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1086                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1087                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1088                synchronized (ActivityManagerService.this) {
1089                    ProcessRecord proc = (ProcessRecord)data.get("app");
1090                    AppErrorResult res = (AppErrorResult) data.get("result");
1091                    if (proc != null && proc.crashDialog != null) {
1092                        Slog.e(TAG, "App already has crash dialog: " + proc);
1093                        if (res != null) {
1094                            res.set(0);
1095                        }
1096                        return;
1097                    }
1098                    if (!showBackground && UserHandle.getAppId(proc.uid)
1099                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1100                            && proc.pid != MY_PID) {
1101                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1102                        if (res != null) {
1103                            res.set(0);
1104                        }
1105                        return;
1106                    }
1107                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1108                        Dialog d = new AppErrorDialog(mContext,
1109                                ActivityManagerService.this, res, proc);
1110                        d.show();
1111                        proc.crashDialog = d;
1112                    } else {
1113                        // The device is asleep, so just pretend that the user
1114                        // saw a crash dialog and hit "force quit".
1115                        if (res != null) {
1116                            res.set(0);
1117                        }
1118                    }
1119                }
1120
1121                ensureBootCompleted();
1122            } break;
1123            case SHOW_NOT_RESPONDING_MSG: {
1124                synchronized (ActivityManagerService.this) {
1125                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1126                    ProcessRecord proc = (ProcessRecord)data.get("app");
1127                    if (proc != null && proc.anrDialog != null) {
1128                        Slog.e(TAG, "App already has anr dialog: " + proc);
1129                        return;
1130                    }
1131
1132                    Intent intent = new Intent("android.intent.action.ANR");
1133                    if (!mProcessesReady) {
1134                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1135                                | Intent.FLAG_RECEIVER_FOREGROUND);
1136                    }
1137                    broadcastIntentLocked(null, null, intent,
1138                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1139                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1140
1141                    if (mShowDialogs) {
1142                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1143                                mContext, proc, (ActivityRecord)data.get("activity"),
1144                                msg.arg1 != 0);
1145                        d.show();
1146                        proc.anrDialog = d;
1147                    } else {
1148                        // Just kill the app if there is no dialog to be shown.
1149                        killAppAtUsersRequest(proc, null);
1150                    }
1151                }
1152
1153                ensureBootCompleted();
1154            } break;
1155            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1156                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1157                synchronized (ActivityManagerService.this) {
1158                    ProcessRecord proc = (ProcessRecord) data.get("app");
1159                    if (proc == null) {
1160                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1161                        break;
1162                    }
1163                    if (proc.crashDialog != null) {
1164                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1165                        return;
1166                    }
1167                    AppErrorResult res = (AppErrorResult) data.get("result");
1168                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1169                        Dialog d = new StrictModeViolationDialog(mContext,
1170                                ActivityManagerService.this, res, proc);
1171                        d.show();
1172                        proc.crashDialog = d;
1173                    } else {
1174                        // The device is asleep, so just pretend that the user
1175                        // saw a crash dialog and hit "force quit".
1176                        res.set(0);
1177                    }
1178                }
1179                ensureBootCompleted();
1180            } break;
1181            case SHOW_FACTORY_ERROR_MSG: {
1182                Dialog d = new FactoryErrorDialog(
1183                    mContext, msg.getData().getCharSequence("msg"));
1184                d.show();
1185                ensureBootCompleted();
1186            } break;
1187            case UPDATE_CONFIGURATION_MSG: {
1188                final ContentResolver resolver = mContext.getContentResolver();
1189                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1190            } break;
1191            case GC_BACKGROUND_PROCESSES_MSG: {
1192                synchronized (ActivityManagerService.this) {
1193                    performAppGcsIfAppropriateLocked();
1194                }
1195            } break;
1196            case WAIT_FOR_DEBUGGER_MSG: {
1197                synchronized (ActivityManagerService.this) {
1198                    ProcessRecord app = (ProcessRecord)msg.obj;
1199                    if (msg.arg1 != 0) {
1200                        if (!app.waitedForDebugger) {
1201                            Dialog d = new AppWaitingForDebuggerDialog(
1202                                    ActivityManagerService.this,
1203                                    mContext, app);
1204                            app.waitDialog = d;
1205                            app.waitedForDebugger = true;
1206                            d.show();
1207                        }
1208                    } else {
1209                        if (app.waitDialog != null) {
1210                            app.waitDialog.dismiss();
1211                            app.waitDialog = null;
1212                        }
1213                    }
1214                }
1215            } break;
1216            case SERVICE_TIMEOUT_MSG: {
1217                if (mDidDexOpt) {
1218                    mDidDexOpt = false;
1219                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1220                    nmsg.obj = msg.obj;
1221                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1222                    return;
1223                }
1224                mServices.serviceTimeout((ProcessRecord)msg.obj);
1225            } break;
1226            case UPDATE_TIME_ZONE: {
1227                synchronized (ActivityManagerService.this) {
1228                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1229                        ProcessRecord r = mLruProcesses.get(i);
1230                        if (r.thread != null) {
1231                            try {
1232                                r.thread.updateTimeZone();
1233                            } catch (RemoteException ex) {
1234                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1235                            }
1236                        }
1237                    }
1238                }
1239            } break;
1240            case CLEAR_DNS_CACHE_MSG: {
1241                synchronized (ActivityManagerService.this) {
1242                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1243                        ProcessRecord r = mLruProcesses.get(i);
1244                        if (r.thread != null) {
1245                            try {
1246                                r.thread.clearDnsCache();
1247                            } catch (RemoteException ex) {
1248                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1249                            }
1250                        }
1251                    }
1252                }
1253            } break;
1254            case UPDATE_HTTP_PROXY_MSG: {
1255                ProxyProperties proxy = (ProxyProperties)msg.obj;
1256                String host = "";
1257                String port = "";
1258                String exclList = "";
1259                String pacFileUrl = null;
1260                if (proxy != null) {
1261                    host = proxy.getHost();
1262                    port = Integer.toString(proxy.getPort());
1263                    exclList = proxy.getExclusionList();
1264                    pacFileUrl = proxy.getPacFileUrl();
1265                }
1266                synchronized (ActivityManagerService.this) {
1267                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1268                        ProcessRecord r = mLruProcesses.get(i);
1269                        if (r.thread != null) {
1270                            try {
1271                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1272                            } catch (RemoteException ex) {
1273                                Slog.w(TAG, "Failed to update http proxy for: " +
1274                                        r.info.processName);
1275                            }
1276                        }
1277                    }
1278                }
1279            } break;
1280            case SHOW_UID_ERROR_MSG: {
1281                String title = "System UIDs Inconsistent";
1282                String text = "UIDs on the system are inconsistent, you need to wipe your"
1283                        + " data partition or your device will be unstable.";
1284                Log.e(TAG, title + ": " + text);
1285                if (mShowDialogs) {
1286                    // XXX This is a temporary dialog, no need to localize.
1287                    AlertDialog d = new BaseErrorDialog(mContext);
1288                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1289                    d.setCancelable(false);
1290                    d.setTitle(title);
1291                    d.setMessage(text);
1292                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1293                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1294                    mUidAlert = d;
1295                    d.show();
1296                }
1297            } break;
1298            case IM_FEELING_LUCKY_MSG: {
1299                if (mUidAlert != null) {
1300                    mUidAlert.dismiss();
1301                    mUidAlert = null;
1302                }
1303            } break;
1304            case PROC_START_TIMEOUT_MSG: {
1305                if (mDidDexOpt) {
1306                    mDidDexOpt = false;
1307                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1308                    nmsg.obj = msg.obj;
1309                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1310                    return;
1311                }
1312                ProcessRecord app = (ProcessRecord)msg.obj;
1313                synchronized (ActivityManagerService.this) {
1314                    processStartTimedOutLocked(app);
1315                }
1316            } break;
1317            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1318                synchronized (ActivityManagerService.this) {
1319                    doPendingActivityLaunchesLocked(true);
1320                }
1321            } break;
1322            case KILL_APPLICATION_MSG: {
1323                synchronized (ActivityManagerService.this) {
1324                    int appid = msg.arg1;
1325                    boolean restart = (msg.arg2 == 1);
1326                    Bundle bundle = (Bundle)msg.obj;
1327                    String pkg = bundle.getString("pkg");
1328                    String reason = bundle.getString("reason");
1329                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1330                            UserHandle.USER_ALL, reason);
1331                }
1332            } break;
1333            case FINALIZE_PENDING_INTENT_MSG: {
1334                ((PendingIntentRecord)msg.obj).completeFinalize();
1335            } break;
1336            case POST_HEAVY_NOTIFICATION_MSG: {
1337                INotificationManager inm = NotificationManager.getService();
1338                if (inm == null) {
1339                    return;
1340                }
1341
1342                ActivityRecord root = (ActivityRecord)msg.obj;
1343                ProcessRecord process = root.app;
1344                if (process == null) {
1345                    return;
1346                }
1347
1348                try {
1349                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1350                    String text = mContext.getString(R.string.heavy_weight_notification,
1351                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1352                    Notification notification = new Notification();
1353                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1354                    notification.when = 0;
1355                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1356                    notification.tickerText = text;
1357                    notification.defaults = 0; // please be quiet
1358                    notification.sound = null;
1359                    notification.vibrate = null;
1360                    notification.setLatestEventInfo(context, text,
1361                            mContext.getText(R.string.heavy_weight_notification_detail),
1362                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1363                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1364                                    new UserHandle(root.userId)));
1365
1366                    try {
1367                        int[] outId = new int[1];
1368                        inm.enqueueNotificationWithTag("android", "android", null,
1369                                R.string.heavy_weight_notification,
1370                                notification, outId, root.userId);
1371                    } catch (RuntimeException e) {
1372                        Slog.w(ActivityManagerService.TAG,
1373                                "Error showing notification for heavy-weight app", e);
1374                    } catch (RemoteException e) {
1375                    }
1376                } catch (NameNotFoundException e) {
1377                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1378                }
1379            } break;
1380            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1381                INotificationManager inm = NotificationManager.getService();
1382                if (inm == null) {
1383                    return;
1384                }
1385                try {
1386                    inm.cancelNotificationWithTag("android", null,
1387                            R.string.heavy_weight_notification,  msg.arg1);
1388                } catch (RuntimeException e) {
1389                    Slog.w(ActivityManagerService.TAG,
1390                            "Error canceling notification for service", e);
1391                } catch (RemoteException e) {
1392                }
1393            } break;
1394            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1395                synchronized (ActivityManagerService.this) {
1396                    checkExcessivePowerUsageLocked(true);
1397                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1398                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1399                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1400                }
1401            } break;
1402            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1403                synchronized (ActivityManagerService.this) {
1404                    ActivityRecord ar = (ActivityRecord)msg.obj;
1405                    if (mCompatModeDialog != null) {
1406                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1407                                ar.info.applicationInfo.packageName)) {
1408                            return;
1409                        }
1410                        mCompatModeDialog.dismiss();
1411                        mCompatModeDialog = null;
1412                    }
1413                    if (ar != null && false) {
1414                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1415                                ar.packageName)) {
1416                            int mode = mCompatModePackages.computeCompatModeLocked(
1417                                    ar.info.applicationInfo);
1418                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1419                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1420                                mCompatModeDialog = new CompatModeDialog(
1421                                        ActivityManagerService.this, mContext,
1422                                        ar.info.applicationInfo);
1423                                mCompatModeDialog.show();
1424                            }
1425                        }
1426                    }
1427                }
1428                break;
1429            }
1430            case DISPATCH_PROCESSES_CHANGED: {
1431                dispatchProcessesChanged();
1432                break;
1433            }
1434            case DISPATCH_PROCESS_DIED: {
1435                final int pid = msg.arg1;
1436                final int uid = msg.arg2;
1437                dispatchProcessDied(pid, uid);
1438                break;
1439            }
1440            case REPORT_MEM_USAGE_MSG: {
1441                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1442                Thread thread = new Thread() {
1443                    @Override public void run() {
1444                        final SparseArray<ProcessMemInfo> infoMap
1445                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1446                        for (int i=0, N=memInfos.size(); i<N; i++) {
1447                            ProcessMemInfo mi = memInfos.get(i);
1448                            infoMap.put(mi.pid, mi);
1449                        }
1450                        updateCpuStatsNow();
1451                        synchronized (mProcessCpuThread) {
1452                            final int N = mProcessCpuTracker.countStats();
1453                            for (int i=0; i<N; i++) {
1454                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1455                                if (st.vsize > 0) {
1456                                    long pss = Debug.getPss(st.pid, null);
1457                                    if (pss > 0) {
1458                                        if (infoMap.indexOfKey(st.pid) < 0) {
1459                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1460                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1461                                            mi.pss = pss;
1462                                            memInfos.add(mi);
1463                                        }
1464                                    }
1465                                }
1466                            }
1467                        }
1468
1469                        long totalPss = 0;
1470                        for (int i=0, N=memInfos.size(); i<N; i++) {
1471                            ProcessMemInfo mi = memInfos.get(i);
1472                            if (mi.pss == 0) {
1473                                mi.pss = Debug.getPss(mi.pid, null);
1474                            }
1475                            totalPss += mi.pss;
1476                        }
1477                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1478                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1479                                if (lhs.oomAdj != rhs.oomAdj) {
1480                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1481                                }
1482                                if (lhs.pss != rhs.pss) {
1483                                    return lhs.pss < rhs.pss ? 1 : -1;
1484                                }
1485                                return 0;
1486                            }
1487                        });
1488
1489                        StringBuilder tag = new StringBuilder(128);
1490                        StringBuilder stack = new StringBuilder(128);
1491                        tag.append("Low on memory -- ");
1492                        appendMemBucket(tag, totalPss, "total", false);
1493                        appendMemBucket(stack, totalPss, "total", true);
1494
1495                        StringBuilder logBuilder = new StringBuilder(1024);
1496                        logBuilder.append("Low on memory:\n");
1497
1498                        boolean firstLine = true;
1499                        int lastOomAdj = Integer.MIN_VALUE;
1500                        for (int i=0, N=memInfos.size(); i<N; i++) {
1501                            ProcessMemInfo mi = memInfos.get(i);
1502
1503                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1504                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1505                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1506                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1507                                if (lastOomAdj != mi.oomAdj) {
1508                                    lastOomAdj = mi.oomAdj;
1509                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1510                                        tag.append(" / ");
1511                                    }
1512                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1513                                        if (firstLine) {
1514                                            stack.append(":");
1515                                            firstLine = false;
1516                                        }
1517                                        stack.append("\n\t at ");
1518                                    } else {
1519                                        stack.append("$");
1520                                    }
1521                                } else {
1522                                    tag.append(" ");
1523                                    stack.append("$");
1524                                }
1525                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1526                                    appendMemBucket(tag, mi.pss, mi.name, false);
1527                                }
1528                                appendMemBucket(stack, mi.pss, mi.name, true);
1529                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1530                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1531                                    stack.append("(");
1532                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1533                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1534                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1535                                            stack.append(":");
1536                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1537                                        }
1538                                    }
1539                                    stack.append(")");
1540                                }
1541                            }
1542
1543                            logBuilder.append("  ");
1544                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1545                            logBuilder.append(' ');
1546                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1547                            logBuilder.append(' ');
1548                            ProcessList.appendRamKb(logBuilder, mi.pss);
1549                            logBuilder.append(" kB: ");
1550                            logBuilder.append(mi.name);
1551                            logBuilder.append(" (");
1552                            logBuilder.append(mi.pid);
1553                            logBuilder.append(") ");
1554                            logBuilder.append(mi.adjType);
1555                            logBuilder.append('\n');
1556                            if (mi.adjReason != null) {
1557                                logBuilder.append("                      ");
1558                                logBuilder.append(mi.adjReason);
1559                                logBuilder.append('\n');
1560                            }
1561                        }
1562
1563                        logBuilder.append("           ");
1564                        ProcessList.appendRamKb(logBuilder, totalPss);
1565                        logBuilder.append(" kB: TOTAL\n");
1566
1567                        long[] infos = new long[Debug.MEMINFO_COUNT];
1568                        Debug.getMemInfo(infos);
1569                        logBuilder.append("  MemInfo: ");
1570                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1571                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1572                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1573                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1574                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1575                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1576                            logBuilder.append("  ZRAM: ");
1577                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1578                            logBuilder.append(" kB RAM, ");
1579                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1580                            logBuilder.append(" kB swap total, ");
1581                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1582                            logBuilder.append(" kB swap free\n");
1583                        }
1584                        Slog.i(TAG, logBuilder.toString());
1585
1586                        StringBuilder dropBuilder = new StringBuilder(1024);
1587                        /*
1588                        StringWriter oomSw = new StringWriter();
1589                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1590                        StringWriter catSw = new StringWriter();
1591                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1592                        String[] emptyArgs = new String[] { };
1593                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1594                        oomPw.flush();
1595                        String oomString = oomSw.toString();
1596                        */
1597                        dropBuilder.append(stack);
1598                        dropBuilder.append('\n');
1599                        dropBuilder.append('\n');
1600                        dropBuilder.append(logBuilder);
1601                        dropBuilder.append('\n');
1602                        /*
1603                        dropBuilder.append(oomString);
1604                        dropBuilder.append('\n');
1605                        */
1606                        StringWriter catSw = new StringWriter();
1607                        synchronized (ActivityManagerService.this) {
1608                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1609                            String[] emptyArgs = new String[] { };
1610                            catPw.println();
1611                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1612                            catPw.println();
1613                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1614                                    false, false, null);
1615                            catPw.println();
1616                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1617                            catPw.flush();
1618                        }
1619                        dropBuilder.append(catSw.toString());
1620                        addErrorToDropBox("lowmem", null, "system_server", null,
1621                                null, tag.toString(), dropBuilder.toString(), null, null);
1622                        //Slog.i(TAG, "Sent to dropbox:");
1623                        //Slog.i(TAG, dropBuilder.toString());
1624                        synchronized (ActivityManagerService.this) {
1625                            long now = SystemClock.uptimeMillis();
1626                            if (mLastMemUsageReportTime < now) {
1627                                mLastMemUsageReportTime = now;
1628                            }
1629                        }
1630                    }
1631                };
1632                thread.start();
1633                break;
1634            }
1635            case REPORT_USER_SWITCH_MSG: {
1636                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1637                break;
1638            }
1639            case CONTINUE_USER_SWITCH_MSG: {
1640                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1641                break;
1642            }
1643            case USER_SWITCH_TIMEOUT_MSG: {
1644                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1645                break;
1646            }
1647            case IMMERSIVE_MODE_LOCK_MSG: {
1648                final boolean nextState = (msg.arg1 != 0);
1649                if (mUpdateLock.isHeld() != nextState) {
1650                    if (DEBUG_IMMERSIVE) {
1651                        final ActivityRecord r = (ActivityRecord) msg.obj;
1652                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1653                    }
1654                    if (nextState) {
1655                        mUpdateLock.acquire();
1656                    } else {
1657                        mUpdateLock.release();
1658                    }
1659                }
1660                break;
1661            }
1662            case PERSIST_URI_GRANTS_MSG: {
1663                writeGrantedUriPermissions();
1664                break;
1665            }
1666            case REQUEST_ALL_PSS_MSG: {
1667                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1668                break;
1669            }
1670            }
1671        }
1672    };
1673
1674    static final int COLLECT_PSS_BG_MSG = 1;
1675
1676    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1677        @Override
1678        public void handleMessage(Message msg) {
1679            switch (msg.what) {
1680            case COLLECT_PSS_BG_MSG: {
1681                int i=0, num=0;
1682                long start = SystemClock.uptimeMillis();
1683                long[] tmp = new long[1];
1684                do {
1685                    ProcessRecord proc;
1686                    int procState;
1687                    int pid;
1688                    synchronized (ActivityManagerService.this) {
1689                        if (i >= mPendingPssProcesses.size()) {
1690                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1691                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1692                            mPendingPssProcesses.clear();
1693                            return;
1694                        }
1695                        proc = mPendingPssProcesses.get(i);
1696                        procState = proc.pssProcState;
1697                        if (proc.thread != null && procState == proc.setProcState) {
1698                            pid = proc.pid;
1699                        } else {
1700                            proc = null;
1701                            pid = 0;
1702                        }
1703                        i++;
1704                    }
1705                    if (proc != null) {
1706                        long pss = Debug.getPss(pid, tmp);
1707                        synchronized (ActivityManagerService.this) {
1708                            if (proc.thread != null && proc.setProcState == procState
1709                                    && proc.pid == pid) {
1710                                num++;
1711                                proc.lastPssTime = SystemClock.uptimeMillis();
1712                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1713                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1714                                        + ": " + pss + " lastPss=" + proc.lastPss
1715                                        + " state=" + ProcessList.makeProcStateString(procState));
1716                                if (proc.initialIdlePss == 0) {
1717                                    proc.initialIdlePss = pss;
1718                                }
1719                                proc.lastPss = pss;
1720                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1721                                    proc.lastCachedPss = pss;
1722                                }
1723                            }
1724                        }
1725                    }
1726                } while (true);
1727            }
1728            }
1729        }
1730    };
1731
1732    public static void setSystemProcess() {
1733        try {
1734            ActivityManagerService m = mSelf;
1735
1736            ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
1737            ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
1738            ServiceManager.addService("meminfo", new MemBinder(m));
1739            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1740            ServiceManager.addService("dbinfo", new DbBinder(m));
1741            if (MONITOR_CPU_USAGE) {
1742                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1743            }
1744            ServiceManager.addService("permission", new PermissionController(m));
1745
1746            ApplicationInfo info =
1747                mSelf.mContext.getPackageManager().getApplicationInfo(
1748                            "android", STOCK_PM_FLAGS);
1749            mSystemThread.installSystemApplicationInfo(info);
1750
1751            synchronized (mSelf) {
1752                ProcessRecord app = mSelf.newProcessRecordLocked(info,
1753                        info.processName, false);
1754                app.persistent = true;
1755                app.pid = MY_PID;
1756                app.maxAdj = ProcessList.SYSTEM_ADJ;
1757                app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats);
1758                mSelf.mProcessNames.put(app.processName, app.uid, app);
1759                synchronized (mSelf.mPidsSelfLocked) {
1760                    mSelf.mPidsSelfLocked.put(app.pid, app);
1761                }
1762                mSelf.updateLruProcessLocked(app, false, null);
1763                mSelf.updateOomAdjLocked();
1764            }
1765        } catch (PackageManager.NameNotFoundException e) {
1766            throw new RuntimeException(
1767                    "Unable to find android system package", e);
1768        }
1769    }
1770
1771    public void setWindowManager(WindowManagerService wm) {
1772        mWindowManager = wm;
1773        mStackSupervisor.setWindowManager(wm);
1774    }
1775
1776    public void startObservingNativeCrashes() {
1777        final NativeCrashListener ncl = new NativeCrashListener();
1778        ncl.start();
1779    }
1780
1781    public static final Context main(int factoryTest) {
1782        AThread thr = new AThread();
1783        thr.start();
1784
1785        synchronized (thr) {
1786            while (thr.mService == null) {
1787                try {
1788                    thr.wait();
1789                } catch (InterruptedException e) {
1790                }
1791            }
1792        }
1793
1794        ActivityManagerService m = thr.mService;
1795        mSelf = m;
1796        ActivityThread at = ActivityThread.systemMain();
1797        mSystemThread = at;
1798        Context context = at.getSystemContext();
1799        context.setTheme(android.R.style.Theme_Holo);
1800        m.mContext = context;
1801        m.mFactoryTest = factoryTest;
1802        m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
1803
1804        m.mStackSupervisor = new ActivityStackSupervisor(m);
1805
1806        m.mBatteryStatsService.publish(context);
1807        m.mUsageStatsService.publish(context);
1808        m.mAppOpsService.publish(context);
1809
1810        synchronized (thr) {
1811            thr.mReady = true;
1812            thr.notifyAll();
1813        }
1814
1815        m.startRunning(null, null, null, null);
1816
1817        return context;
1818    }
1819
1820    public static ActivityManagerService self() {
1821        return mSelf;
1822    }
1823
1824    public IAppOpsService getAppOpsService() {
1825        return mAppOpsService;
1826    }
1827
1828    static class AThread extends Thread {
1829        ActivityManagerService mService;
1830        Looper mLooper;
1831        boolean mReady = false;
1832
1833        public AThread() {
1834            super("ActivityManager");
1835        }
1836
1837        @Override
1838        public void run() {
1839            Looper.prepare();
1840
1841            android.os.Process.setThreadPriority(
1842                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1843            android.os.Process.setCanSelfBackground(false);
1844
1845            ActivityManagerService m = new ActivityManagerService();
1846
1847            synchronized (this) {
1848                mService = m;
1849                mLooper = Looper.myLooper();
1850                Watchdog.getInstance().addThread(new Handler(mLooper), getName());
1851                notifyAll();
1852            }
1853
1854            synchronized (this) {
1855                while (!mReady) {
1856                    try {
1857                        wait();
1858                    } catch (InterruptedException e) {
1859                    }
1860                }
1861            }
1862
1863            // For debug builds, log event loop stalls to dropbox for analysis.
1864            if (StrictMode.conditionallyEnableDebugLogging()) {
1865                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1866            }
1867
1868            Looper.loop();
1869        }
1870    }
1871
1872    static class MemBinder extends Binder {
1873        ActivityManagerService mActivityManagerService;
1874        MemBinder(ActivityManagerService activityManagerService) {
1875            mActivityManagerService = activityManagerService;
1876        }
1877
1878        @Override
1879        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1880            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1881                    != PackageManager.PERMISSION_GRANTED) {
1882                pw.println("Permission Denial: can't dump meminfo from from pid="
1883                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1884                        + " without permission " + android.Manifest.permission.DUMP);
1885                return;
1886            }
1887
1888            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1889        }
1890    }
1891
1892    static class GraphicsBinder extends Binder {
1893        ActivityManagerService mActivityManagerService;
1894        GraphicsBinder(ActivityManagerService activityManagerService) {
1895            mActivityManagerService = activityManagerService;
1896        }
1897
1898        @Override
1899        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1900            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1901                    != PackageManager.PERMISSION_GRANTED) {
1902                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1903                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1904                        + " without permission " + android.Manifest.permission.DUMP);
1905                return;
1906            }
1907
1908            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1909        }
1910    }
1911
1912    static class DbBinder extends Binder {
1913        ActivityManagerService mActivityManagerService;
1914        DbBinder(ActivityManagerService activityManagerService) {
1915            mActivityManagerService = activityManagerService;
1916        }
1917
1918        @Override
1919        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1920            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1921                    != PackageManager.PERMISSION_GRANTED) {
1922                pw.println("Permission Denial: can't dump dbinfo from from pid="
1923                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1924                        + " without permission " + android.Manifest.permission.DUMP);
1925                return;
1926            }
1927
1928            mActivityManagerService.dumpDbInfo(fd, pw, args);
1929        }
1930    }
1931
1932    static class CpuBinder extends Binder {
1933        ActivityManagerService mActivityManagerService;
1934        CpuBinder(ActivityManagerService activityManagerService) {
1935            mActivityManagerService = activityManagerService;
1936        }
1937
1938        @Override
1939        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1940            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1941                    != PackageManager.PERMISSION_GRANTED) {
1942                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1943                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1944                        + " without permission " + android.Manifest.permission.DUMP);
1945                return;
1946            }
1947
1948            synchronized (mActivityManagerService.mProcessCpuThread) {
1949                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1950                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1951                        SystemClock.uptimeMillis()));
1952            }
1953        }
1954    }
1955
1956    private ActivityManagerService() {
1957        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1958
1959        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false);
1960        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true);
1961        mBroadcastQueues[0] = mFgBroadcastQueue;
1962        mBroadcastQueues[1] = mBgBroadcastQueue;
1963
1964        mServices = new ActiveServices(this);
1965        mProviderMap = new ProviderMap(this);
1966
1967        File dataDir = Environment.getDataDirectory();
1968        File systemDir = new File(dataDir, "system");
1969        systemDir.mkdirs();
1970        mBatteryStatsService = new BatteryStatsService(new File(
1971                systemDir, "batterystats.bin").toString());
1972        mBatteryStatsService.getActiveStatistics().readLocked();
1973        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1974        mOnBattery = DEBUG_POWER ? true
1975                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1976        mBatteryStatsService.getActiveStatistics().setCallback(this);
1977
1978        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1979
1980        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1981        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
1982
1983        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1984
1985        // User 0 is the first and only user that runs at boot.
1986        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1987        mUserLru.add(Integer.valueOf(0));
1988        updateStartedUserArrayLocked();
1989
1990        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1991            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1992
1993        mConfiguration.setToDefaults();
1994        mConfiguration.setLocale(Locale.getDefault());
1995
1996        mConfigurationSeq = mConfiguration.seq = 1;
1997        mProcessCpuTracker.init();
1998
1999        mCompatModePackages = new CompatModePackages(this, systemDir);
2000
2001        // Add ourself to the Watchdog monitors.
2002        Watchdog.getInstance().addMonitor(this);
2003
2004        mProcessCpuThread = new Thread("CpuTracker") {
2005            @Override
2006            public void run() {
2007                while (true) {
2008                    try {
2009                        try {
2010                            synchronized(this) {
2011                                final long now = SystemClock.uptimeMillis();
2012                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2013                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2014                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2015                                //        + ", write delay=" + nextWriteDelay);
2016                                if (nextWriteDelay < nextCpuDelay) {
2017                                    nextCpuDelay = nextWriteDelay;
2018                                }
2019                                if (nextCpuDelay > 0) {
2020                                    mProcessCpuMutexFree.set(true);
2021                                    this.wait(nextCpuDelay);
2022                                }
2023                            }
2024                        } catch (InterruptedException e) {
2025                        }
2026                        updateCpuStatsNow();
2027                    } catch (Exception e) {
2028                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2029                    }
2030                }
2031            }
2032        };
2033        mProcessCpuThread.start();
2034    }
2035
2036    @Override
2037    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2038            throws RemoteException {
2039        if (code == SYSPROPS_TRANSACTION) {
2040            // We need to tell all apps about the system property change.
2041            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2042            synchronized(this) {
2043                final int NP = mProcessNames.getMap().size();
2044                for (int ip=0; ip<NP; ip++) {
2045                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2046                    final int NA = apps.size();
2047                    for (int ia=0; ia<NA; ia++) {
2048                        ProcessRecord app = apps.valueAt(ia);
2049                        if (app.thread != null) {
2050                            procs.add(app.thread.asBinder());
2051                        }
2052                    }
2053                }
2054            }
2055
2056            int N = procs.size();
2057            for (int i=0; i<N; i++) {
2058                Parcel data2 = Parcel.obtain();
2059                try {
2060                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2061                } catch (RemoteException e) {
2062                }
2063                data2.recycle();
2064            }
2065        }
2066        try {
2067            return super.onTransact(code, data, reply, flags);
2068        } catch (RuntimeException e) {
2069            // The activity manager only throws security exceptions, so let's
2070            // log all others.
2071            if (!(e instanceof SecurityException)) {
2072                Slog.wtf(TAG, "Activity Manager Crash", e);
2073            }
2074            throw e;
2075        }
2076    }
2077
2078    void updateCpuStats() {
2079        final long now = SystemClock.uptimeMillis();
2080        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2081            return;
2082        }
2083        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2084            synchronized (mProcessCpuThread) {
2085                mProcessCpuThread.notify();
2086            }
2087        }
2088    }
2089
2090    void updateCpuStatsNow() {
2091        synchronized (mProcessCpuThread) {
2092            mProcessCpuMutexFree.set(false);
2093            final long now = SystemClock.uptimeMillis();
2094            boolean haveNewCpuStats = false;
2095
2096            if (MONITOR_CPU_USAGE &&
2097                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2098                mLastCpuTime.set(now);
2099                haveNewCpuStats = true;
2100                mProcessCpuTracker.update();
2101                //Slog.i(TAG, mProcessCpu.printCurrentState());
2102                //Slog.i(TAG, "Total CPU usage: "
2103                //        + mProcessCpu.getTotalCpuPercent() + "%");
2104
2105                // Slog the cpu usage if the property is set.
2106                if ("true".equals(SystemProperties.get("events.cpu"))) {
2107                    int user = mProcessCpuTracker.getLastUserTime();
2108                    int system = mProcessCpuTracker.getLastSystemTime();
2109                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2110                    int irq = mProcessCpuTracker.getLastIrqTime();
2111                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2112                    int idle = mProcessCpuTracker.getLastIdleTime();
2113
2114                    int total = user + system + iowait + irq + softIrq + idle;
2115                    if (total == 0) total = 1;
2116
2117                    EventLog.writeEvent(EventLogTags.CPU,
2118                            ((user+system+iowait+irq+softIrq) * 100) / total,
2119                            (user * 100) / total,
2120                            (system * 100) / total,
2121                            (iowait * 100) / total,
2122                            (irq * 100) / total,
2123                            (softIrq * 100) / total);
2124                }
2125            }
2126
2127            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2128            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2129            synchronized(bstats) {
2130                synchronized(mPidsSelfLocked) {
2131                    if (haveNewCpuStats) {
2132                        if (mOnBattery) {
2133                            int perc = bstats.startAddingCpuLocked();
2134                            int totalUTime = 0;
2135                            int totalSTime = 0;
2136                            final int N = mProcessCpuTracker.countStats();
2137                            for (int i=0; i<N; i++) {
2138                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2139                                if (!st.working) {
2140                                    continue;
2141                                }
2142                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2143                                int otherUTime = (st.rel_utime*perc)/100;
2144                                int otherSTime = (st.rel_stime*perc)/100;
2145                                totalUTime += otherUTime;
2146                                totalSTime += otherSTime;
2147                                if (pr != null) {
2148                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2149                                            st.name, st.pid);
2150                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2151                                            st.rel_stime-otherSTime);
2152                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2153                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2154                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2155                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2156                                    if (ps == null) {
2157                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2158                                                "(Unknown)");
2159                                    }
2160                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2161                                            st.rel_stime-otherSTime);
2162                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2163                                } else {
2164                                    BatteryStatsImpl.Uid.Proc ps =
2165                                            bstats.getProcessStatsLocked(st.name, st.pid);
2166                                    if (ps != null) {
2167                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2168                                                st.rel_stime-otherSTime);
2169                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2170                                    }
2171                                }
2172                            }
2173                            bstats.finishAddingCpuLocked(perc, totalUTime,
2174                                    totalSTime, cpuSpeedTimes);
2175                        }
2176                    }
2177                }
2178
2179                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2180                    mLastWriteTime = now;
2181                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2182                }
2183            }
2184        }
2185    }
2186
2187    @Override
2188    public void batteryNeedsCpuUpdate() {
2189        updateCpuStatsNow();
2190    }
2191
2192    @Override
2193    public void batteryPowerChanged(boolean onBattery) {
2194        // When plugging in, update the CPU stats first before changing
2195        // the plug state.
2196        updateCpuStatsNow();
2197        synchronized (this) {
2198            synchronized(mPidsSelfLocked) {
2199                mOnBattery = DEBUG_POWER ? true : onBattery;
2200            }
2201        }
2202    }
2203
2204    /**
2205     * Initialize the application bind args. These are passed to each
2206     * process when the bindApplication() IPC is sent to the process. They're
2207     * lazily setup to make sure the services are running when they're asked for.
2208     */
2209    private HashMap<String, IBinder> getCommonServicesLocked() {
2210        if (mAppBindArgs == null) {
2211            mAppBindArgs = new HashMap<String, IBinder>();
2212
2213            // Setup the application init args
2214            mAppBindArgs.put("package", ServiceManager.getService("package"));
2215            mAppBindArgs.put("window", ServiceManager.getService("window"));
2216            mAppBindArgs.put(Context.ALARM_SERVICE,
2217                    ServiceManager.getService(Context.ALARM_SERVICE));
2218        }
2219        return mAppBindArgs;
2220    }
2221
2222    final void setFocusedActivityLocked(ActivityRecord r) {
2223        if (mFocusedActivity != r) {
2224            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2225            mFocusedActivity = r;
2226            mStackSupervisor.setFocusedStack(r);
2227            if (r != null) {
2228                mWindowManager.setFocusedApp(r.appToken, true);
2229            }
2230            applyUpdateLockStateLocked(r);
2231        }
2232    }
2233
2234    @Override
2235    public void setFocusedStack(int stackId) {
2236        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2237        synchronized (ActivityManagerService.this) {
2238            ActivityStack stack = mStackSupervisor.getStack(stackId);
2239            if (stack != null) {
2240                ActivityRecord r = stack.topRunningActivityLocked(null);
2241                if (r != null) {
2242                    setFocusedActivityLocked(r);
2243                }
2244            }
2245        }
2246    }
2247
2248    @Override
2249    public void notifyActivityDrawn(IBinder token) {
2250        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2251        synchronized (this) {
2252            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2253            if (r != null) {
2254                r.task.stack.notifyActivityDrawnLocked(r);
2255            }
2256        }
2257    }
2258
2259    final void applyUpdateLockStateLocked(ActivityRecord r) {
2260        // Modifications to the UpdateLock state are done on our handler, outside
2261        // the activity manager's locks.  The new state is determined based on the
2262        // state *now* of the relevant activity record.  The object is passed to
2263        // the handler solely for logging detail, not to be consulted/modified.
2264        final boolean nextState = r != null && r.immersive;
2265        mHandler.sendMessage(
2266                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2267    }
2268
2269    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2270        Message msg = Message.obtain();
2271        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2272        msg.obj = r.task.askedCompatMode ? null : r;
2273        mHandler.sendMessage(msg);
2274    }
2275
2276    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2277            String what, Object obj, ProcessRecord srcApp) {
2278        app.lastActivityTime = now;
2279
2280        if (app.activities.size() > 0) {
2281            // Don't want to touch dependent processes that are hosting activities.
2282            return index;
2283        }
2284
2285        int lrui = mLruProcesses.lastIndexOf(app);
2286        if (lrui < 0) {
2287            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2288                    + what + " " + obj + " from " + srcApp);
2289            return index;
2290        }
2291
2292        if (lrui >= index) {
2293            // Don't want to cause this to move dependent processes *back* in the
2294            // list as if they were less frequently used.
2295            return index;
2296        }
2297
2298        if (lrui >= mLruProcessActivityStart) {
2299            // Don't want to touch dependent processes that are hosting activities.
2300            return index;
2301        }
2302
2303        mLruProcesses.remove(lrui);
2304        if (index > 0) {
2305            index--;
2306        }
2307        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2308                + " in LRU list: " + app);
2309        mLruProcesses.add(index, app);
2310        return index;
2311    }
2312
2313    final void removeLruProcessLocked(ProcessRecord app) {
2314        int lrui = mLruProcesses.lastIndexOf(app);
2315        if (lrui >= 0) {
2316            if (lrui <= mLruProcessActivityStart) {
2317                mLruProcessActivityStart--;
2318            }
2319            if (lrui <= mLruProcessServiceStart) {
2320                mLruProcessServiceStart--;
2321            }
2322            mLruProcesses.remove(lrui);
2323        }
2324    }
2325
2326    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2327            ProcessRecord client) {
2328        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2329        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2330        if (!activityChange && hasActivity) {
2331            // The process has activties, so we are only going to allow activity-based
2332            // adjustments move it.  It should be kept in the front of the list with other
2333            // processes that have activities, and we don't want those to change their
2334            // order except due to activity operations.
2335            return;
2336        }
2337
2338        mLruSeq++;
2339        final long now = SystemClock.uptimeMillis();
2340        app.lastActivityTime = now;
2341
2342        // First a quick reject: if the app is already at the position we will
2343        // put it, then there is nothing to do.
2344        if (hasActivity) {
2345            final int N = mLruProcesses.size();
2346            if (N > 0 && mLruProcesses.get(N-1) == app) {
2347                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2348                return;
2349            }
2350        } else {
2351            if (mLruProcessServiceStart > 0
2352                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2353                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2354                return;
2355            }
2356        }
2357
2358        int lrui = mLruProcesses.lastIndexOf(app);
2359
2360        if (app.persistent && lrui >= 0) {
2361            // We don't care about the position of persistent processes, as long as
2362            // they are in the list.
2363            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2364            return;
2365        }
2366
2367        /* In progress: compute new position first, so we can avoid doing work
2368           if the process is not actually going to move.  Not yet working.
2369        int addIndex;
2370        int nextIndex;
2371        boolean inActivity = false, inService = false;
2372        if (hasActivity) {
2373            // Process has activities, put it at the very tipsy-top.
2374            addIndex = mLruProcesses.size();
2375            nextIndex = mLruProcessServiceStart;
2376            inActivity = true;
2377        } else if (hasService) {
2378            // Process has services, put it at the top of the service list.
2379            addIndex = mLruProcessActivityStart;
2380            nextIndex = mLruProcessServiceStart;
2381            inActivity = true;
2382            inService = true;
2383        } else  {
2384            // Process not otherwise of interest, it goes to the top of the non-service area.
2385            addIndex = mLruProcessServiceStart;
2386            if (client != null) {
2387                int clientIndex = mLruProcesses.lastIndexOf(client);
2388                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2389                        + app);
2390                if (clientIndex >= 0 && addIndex > clientIndex) {
2391                    addIndex = clientIndex;
2392                }
2393            }
2394            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2395        }
2396
2397        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2398                + mLruProcessActivityStart + "): " + app);
2399        */
2400
2401        if (lrui >= 0) {
2402            if (lrui < mLruProcessActivityStart) {
2403                mLruProcessActivityStart--;
2404            }
2405            if (lrui < mLruProcessServiceStart) {
2406                mLruProcessServiceStart--;
2407            }
2408            /*
2409            if (addIndex > lrui) {
2410                addIndex--;
2411            }
2412            if (nextIndex > lrui) {
2413                nextIndex--;
2414            }
2415            */
2416            mLruProcesses.remove(lrui);
2417        }
2418
2419        /*
2420        mLruProcesses.add(addIndex, app);
2421        if (inActivity) {
2422            mLruProcessActivityStart++;
2423        }
2424        if (inService) {
2425            mLruProcessActivityStart++;
2426        }
2427        */
2428
2429        int nextIndex;
2430        if (hasActivity) {
2431            final int N = mLruProcesses.size();
2432            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2433                // Process doesn't have activities, but has clients with
2434                // activities...  move it up, but one below the top (the top
2435                // should always have a real activity).
2436                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2437                mLruProcesses.add(N-1, app);
2438                // To keep it from spamming the LRU list (by making a bunch of clients),
2439                // we will push down any other entries owned by the app.
2440                final int uid = app.info.uid;
2441                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2442                    ProcessRecord subProc = mLruProcesses.get(i);
2443                    if (subProc.info.uid == uid) {
2444                        // We want to push this one down the list.  If the process after
2445                        // it is for the same uid, however, don't do so, because we don't
2446                        // want them internally to be re-ordered.
2447                        if (mLruProcesses.get(i-1).info.uid != uid) {
2448                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2449                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2450                            ProcessRecord tmp = mLruProcesses.get(i);
2451                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2452                            mLruProcesses.set(i-1, tmp);
2453                            i--;
2454                        }
2455                    } else {
2456                        // A gap, we can stop here.
2457                        break;
2458                    }
2459                }
2460            } else {
2461                // Process has activities, put it at the very tipsy-top.
2462                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2463                mLruProcesses.add(app);
2464            }
2465            nextIndex = mLruProcessServiceStart;
2466        } else if (hasService) {
2467            // Process has services, put it at the top of the service list.
2468            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2469            mLruProcesses.add(mLruProcessActivityStart, app);
2470            nextIndex = mLruProcessServiceStart;
2471            mLruProcessActivityStart++;
2472        } else  {
2473            // Process not otherwise of interest, it goes to the top of the non-service area.
2474            int index = mLruProcessServiceStart;
2475            if (client != null) {
2476                // If there is a client, don't allow the process to be moved up higher
2477                // in the list than that client.
2478                int clientIndex = mLruProcesses.lastIndexOf(client);
2479                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2480                        + " when updating " + app);
2481                if (clientIndex <= lrui) {
2482                    // Don't allow the client index restriction to push it down farther in the
2483                    // list than it already is.
2484                    clientIndex = lrui;
2485                }
2486                if (clientIndex >= 0 && index > clientIndex) {
2487                    index = clientIndex;
2488                }
2489            }
2490            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2491            mLruProcesses.add(index, app);
2492            nextIndex = index-1;
2493            mLruProcessActivityStart++;
2494            mLruProcessServiceStart++;
2495        }
2496
2497        // If the app is currently using a content provider or service,
2498        // bump those processes as well.
2499        for (int j=app.connections.size()-1; j>=0; j--) {
2500            ConnectionRecord cr = app.connections.valueAt(j);
2501            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2502                    && cr.binding.service.app != null
2503                    && cr.binding.service.app.lruSeq != mLruSeq
2504                    && !cr.binding.service.app.persistent) {
2505                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2506                        "service connection", cr, app);
2507            }
2508        }
2509        for (int j=app.conProviders.size()-1; j>=0; j--) {
2510            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2511            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2512                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2513                        "provider reference", cpr, app);
2514            }
2515        }
2516    }
2517
2518    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2519        if (uid == Process.SYSTEM_UID) {
2520            // The system gets to run in any process.  If there are multiple
2521            // processes with the same uid, just pick the first (this
2522            // should never happen).
2523            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2524            if (procs == null) return null;
2525            final int N = procs.size();
2526            for (int i = 0; i < N; i++) {
2527                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2528            }
2529        }
2530        ProcessRecord proc = mProcessNames.get(processName, uid);
2531        if (false && proc != null && !keepIfLarge
2532                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2533                && proc.lastCachedPss >= 4000) {
2534            // Turn this condition on to cause killing to happen regularly, for testing.
2535            if (proc.baseProcessTracker != null) {
2536                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2537            }
2538            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2539                    + "k from cached");
2540        } else if (proc != null && !keepIfLarge
2541                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2542                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2543            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2544            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2545                if (proc.baseProcessTracker != null) {
2546                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2547                }
2548                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2549                        + "k from cached");
2550            }
2551        }
2552        return proc;
2553    }
2554
2555    void ensurePackageDexOpt(String packageName) {
2556        IPackageManager pm = AppGlobals.getPackageManager();
2557        try {
2558            if (pm.performDexOpt(packageName)) {
2559                mDidDexOpt = true;
2560            }
2561        } catch (RemoteException e) {
2562        }
2563    }
2564
2565    boolean isNextTransitionForward() {
2566        int transit = mWindowManager.getPendingAppTransition();
2567        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2568                || transit == AppTransition.TRANSIT_TASK_OPEN
2569                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2570    }
2571
2572    final ProcessRecord startProcessLocked(String processName,
2573            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2574            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2575            boolean isolated, boolean keepIfLarge) {
2576        ProcessRecord app;
2577        if (!isolated) {
2578            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2579        } else {
2580            // If this is an isolated process, it can't re-use an existing process.
2581            app = null;
2582        }
2583        // We don't have to do anything more if:
2584        // (1) There is an existing application record; and
2585        // (2) The caller doesn't think it is dead, OR there is no thread
2586        //     object attached to it so we know it couldn't have crashed; and
2587        // (3) There is a pid assigned to it, so it is either starting or
2588        //     already running.
2589        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2590                + " app=" + app + " knownToBeDead=" + knownToBeDead
2591                + " thread=" + (app != null ? app.thread : null)
2592                + " pid=" + (app != null ? app.pid : -1));
2593        if (app != null && app.pid > 0) {
2594            if (!knownToBeDead || app.thread == null) {
2595                // We already have the app running, or are waiting for it to
2596                // come up (we have a pid but not yet its thread), so keep it.
2597                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2598                // If this is a new package in the process, add the package to the list
2599                app.addPackage(info.packageName, mProcessStats);
2600                return app;
2601            }
2602
2603            // An application record is attached to a previous process,
2604            // clean it up now.
2605            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2606            handleAppDiedLocked(app, true, true);
2607        }
2608
2609        String hostingNameStr = hostingName != null
2610                ? hostingName.flattenToShortString() : null;
2611
2612        if (!isolated) {
2613            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2614                // If we are in the background, then check to see if this process
2615                // is bad.  If so, we will just silently fail.
2616                if (mBadProcesses.get(info.processName, info.uid) != null) {
2617                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2618                            + "/" + info.processName);
2619                    return null;
2620                }
2621            } else {
2622                // When the user is explicitly starting a process, then clear its
2623                // crash count so that we won't make it bad until they see at
2624                // least one crash dialog again, and make the process good again
2625                // if it had been bad.
2626                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2627                        + "/" + info.processName);
2628                mProcessCrashTimes.remove(info.processName, info.uid);
2629                if (mBadProcesses.get(info.processName, info.uid) != null) {
2630                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2631                            UserHandle.getUserId(info.uid), info.uid,
2632                            info.processName);
2633                    mBadProcesses.remove(info.processName, info.uid);
2634                    if (app != null) {
2635                        app.bad = false;
2636                    }
2637                }
2638            }
2639        }
2640
2641        if (app == null) {
2642            app = newProcessRecordLocked(info, processName, isolated);
2643            if (app == null) {
2644                Slog.w(TAG, "Failed making new process record for "
2645                        + processName + "/" + info.uid + " isolated=" + isolated);
2646                return null;
2647            }
2648            mProcessNames.put(processName, app.uid, app);
2649            if (isolated) {
2650                mIsolatedProcesses.put(app.uid, app);
2651            }
2652        } else {
2653            // If this is a new package in the process, add the package to the list
2654            app.addPackage(info.packageName, mProcessStats);
2655        }
2656
2657        // If the system is not ready yet, then hold off on starting this
2658        // process until it is.
2659        if (!mProcessesReady
2660                && !isAllowedWhileBooting(info)
2661                && !allowWhileBooting) {
2662            if (!mProcessesOnHold.contains(app)) {
2663                mProcessesOnHold.add(app);
2664            }
2665            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2666            return app;
2667        }
2668
2669        startProcessLocked(app, hostingType, hostingNameStr);
2670        return (app.pid != 0) ? app : null;
2671    }
2672
2673    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2674        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2675    }
2676
2677    private final void startProcessLocked(ProcessRecord app,
2678            String hostingType, String hostingNameStr) {
2679        if (app.pid > 0 && app.pid != MY_PID) {
2680            synchronized (mPidsSelfLocked) {
2681                mPidsSelfLocked.remove(app.pid);
2682                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2683            }
2684            app.setPid(0);
2685        }
2686
2687        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2688                "startProcessLocked removing on hold: " + app);
2689        mProcessesOnHold.remove(app);
2690
2691        updateCpuStats();
2692
2693        try {
2694            int uid = app.uid;
2695
2696            int[] gids = null;
2697            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2698            if (!app.isolated) {
2699                int[] permGids = null;
2700                try {
2701                    final PackageManager pm = mContext.getPackageManager();
2702                    permGids = pm.getPackageGids(app.info.packageName);
2703
2704                    if (Environment.isExternalStorageEmulated()) {
2705                        if (pm.checkPermission(
2706                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2707                                app.info.packageName) == PERMISSION_GRANTED) {
2708                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2709                        } else {
2710                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2711                        }
2712                    }
2713                } catch (PackageManager.NameNotFoundException e) {
2714                    Slog.w(TAG, "Unable to retrieve gids", e);
2715                }
2716
2717                /*
2718                 * Add shared application GID so applications can share some
2719                 * resources like shared libraries
2720                 */
2721                if (permGids == null) {
2722                    gids = new int[1];
2723                } else {
2724                    gids = new int[permGids.length + 1];
2725                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2726                }
2727                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2728            }
2729            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2730                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2731                        && mTopComponent != null
2732                        && app.processName.equals(mTopComponent.getPackageName())) {
2733                    uid = 0;
2734                }
2735                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2736                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2737                    uid = 0;
2738                }
2739            }
2740            int debugFlags = 0;
2741            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2742                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2743                // Also turn on CheckJNI for debuggable apps. It's quite
2744                // awkward to turn on otherwise.
2745                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2746            }
2747            // Run the app in safe mode if its manifest requests so or the
2748            // system is booted in safe mode.
2749            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2750                Zygote.systemInSafeMode == true) {
2751                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2752            }
2753            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2754                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2755            }
2756            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2757                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2758            }
2759            if ("1".equals(SystemProperties.get("debug.assert"))) {
2760                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2761            }
2762
2763            // Start the process.  It will either succeed and return a result containing
2764            // the PID of the new process, or else throw a RuntimeException.
2765            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2766                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2767                    app.info.targetSdkVersion, app.info.seinfo, null);
2768
2769            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2770            synchronized (bs) {
2771                if (bs.isOnBattery()) {
2772                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2773                }
2774            }
2775
2776            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2777                    UserHandle.getUserId(uid), startResult.pid, uid,
2778                    app.processName, hostingType,
2779                    hostingNameStr != null ? hostingNameStr : "");
2780
2781            if (app.persistent) {
2782                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2783            }
2784
2785            StringBuilder buf = mStringBuilder;
2786            buf.setLength(0);
2787            buf.append("Start proc ");
2788            buf.append(app.processName);
2789            buf.append(" for ");
2790            buf.append(hostingType);
2791            if (hostingNameStr != null) {
2792                buf.append(" ");
2793                buf.append(hostingNameStr);
2794            }
2795            buf.append(": pid=");
2796            buf.append(startResult.pid);
2797            buf.append(" uid=");
2798            buf.append(uid);
2799            buf.append(" gids={");
2800            if (gids != null) {
2801                for (int gi=0; gi<gids.length; gi++) {
2802                    if (gi != 0) buf.append(", ");
2803                    buf.append(gids[gi]);
2804
2805                }
2806            }
2807            buf.append("}");
2808            Slog.i(TAG, buf.toString());
2809            app.setPid(startResult.pid);
2810            app.usingWrapper = startResult.usingWrapper;
2811            app.removed = false;
2812            synchronized (mPidsSelfLocked) {
2813                this.mPidsSelfLocked.put(startResult.pid, app);
2814                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2815                msg.obj = app;
2816                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2817                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2818            }
2819        } catch (RuntimeException e) {
2820            // XXX do better error recovery.
2821            app.setPid(0);
2822            Slog.e(TAG, "Failure starting process " + app.processName, e);
2823        }
2824    }
2825
2826    void updateUsageStats(ActivityRecord component, boolean resumed) {
2827        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2828        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2829        if (resumed) {
2830            mUsageStatsService.noteResumeComponent(component.realActivity);
2831            synchronized (stats) {
2832                stats.noteActivityResumedLocked(component.app.uid);
2833            }
2834        } else {
2835            mUsageStatsService.notePauseComponent(component.realActivity);
2836            synchronized (stats) {
2837                stats.noteActivityPausedLocked(component.app.uid);
2838            }
2839        }
2840    }
2841
2842    Intent getHomeIntent() {
2843        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2844        intent.setComponent(mTopComponent);
2845        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2846            intent.addCategory(Intent.CATEGORY_HOME);
2847        }
2848        return intent;
2849    }
2850
2851    boolean startHomeActivityLocked(int userId) {
2852        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2853                && mTopAction == null) {
2854            // We are running in factory test mode, but unable to find
2855            // the factory test app, so just sit around displaying the
2856            // error message and don't try to start anything.
2857            return false;
2858        }
2859        Intent intent = getHomeIntent();
2860        ActivityInfo aInfo =
2861            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2862        if (aInfo != null) {
2863            intent.setComponent(new ComponentName(
2864                    aInfo.applicationInfo.packageName, aInfo.name));
2865            // Don't do this if the home app is currently being
2866            // instrumented.
2867            aInfo = new ActivityInfo(aInfo);
2868            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2869            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2870                    aInfo.applicationInfo.uid, true);
2871            if (app == null || app.instrumentationClass == null) {
2872                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2873                mStackSupervisor.startHomeActivity(intent, aInfo);
2874            }
2875        }
2876
2877        return true;
2878    }
2879
2880    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2881        ActivityInfo ai = null;
2882        ComponentName comp = intent.getComponent();
2883        try {
2884            if (comp != null) {
2885                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2886            } else {
2887                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2888                        intent,
2889                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2890                            flags, userId);
2891
2892                if (info != null) {
2893                    ai = info.activityInfo;
2894                }
2895            }
2896        } catch (RemoteException e) {
2897            // ignore
2898        }
2899
2900        return ai;
2901    }
2902
2903    /**
2904     * Starts the "new version setup screen" if appropriate.
2905     */
2906    void startSetupActivityLocked() {
2907        // Only do this once per boot.
2908        if (mCheckedForSetup) {
2909            return;
2910        }
2911
2912        // We will show this screen if the current one is a different
2913        // version than the last one shown, and we are not running in
2914        // low-level factory test mode.
2915        final ContentResolver resolver = mContext.getContentResolver();
2916        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2917                Settings.Global.getInt(resolver,
2918                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2919            mCheckedForSetup = true;
2920
2921            // See if we should be showing the platform update setup UI.
2922            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2923            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2924                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2925
2926            // We don't allow third party apps to replace this.
2927            ResolveInfo ri = null;
2928            for (int i=0; ris != null && i<ris.size(); i++) {
2929                if ((ris.get(i).activityInfo.applicationInfo.flags
2930                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2931                    ri = ris.get(i);
2932                    break;
2933                }
2934            }
2935
2936            if (ri != null) {
2937                String vers = ri.activityInfo.metaData != null
2938                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2939                        : null;
2940                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2941                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2942                            Intent.METADATA_SETUP_VERSION);
2943                }
2944                String lastVers = Settings.Secure.getString(
2945                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2946                if (vers != null && !vers.equals(lastVers)) {
2947                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2948                    intent.setComponent(new ComponentName(
2949                            ri.activityInfo.packageName, ri.activityInfo.name));
2950                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2951                            null, null, 0, 0, 0, null, 0, null, false, null);
2952                }
2953            }
2954        }
2955    }
2956
2957    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2958        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2959    }
2960
2961    void enforceNotIsolatedCaller(String caller) {
2962        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2963            throw new SecurityException("Isolated process not allowed to call " + caller);
2964        }
2965    }
2966
2967    @Override
2968    public int getFrontActivityScreenCompatMode() {
2969        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2970        synchronized (this) {
2971            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2972        }
2973    }
2974
2975    @Override
2976    public void setFrontActivityScreenCompatMode(int mode) {
2977        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2978                "setFrontActivityScreenCompatMode");
2979        synchronized (this) {
2980            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2981        }
2982    }
2983
2984    @Override
2985    public int getPackageScreenCompatMode(String packageName) {
2986        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2987        synchronized (this) {
2988            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2989        }
2990    }
2991
2992    @Override
2993    public void setPackageScreenCompatMode(String packageName, int mode) {
2994        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2995                "setPackageScreenCompatMode");
2996        synchronized (this) {
2997            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2998        }
2999    }
3000
3001    @Override
3002    public boolean getPackageAskScreenCompat(String packageName) {
3003        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3004        synchronized (this) {
3005            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3006        }
3007    }
3008
3009    @Override
3010    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3011        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3012                "setPackageAskScreenCompat");
3013        synchronized (this) {
3014            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3015        }
3016    }
3017
3018    private void dispatchProcessesChanged() {
3019        int N;
3020        synchronized (this) {
3021            N = mPendingProcessChanges.size();
3022            if (mActiveProcessChanges.length < N) {
3023                mActiveProcessChanges = new ProcessChangeItem[N];
3024            }
3025            mPendingProcessChanges.toArray(mActiveProcessChanges);
3026            mAvailProcessChanges.addAll(mPendingProcessChanges);
3027            mPendingProcessChanges.clear();
3028            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3029        }
3030
3031        int i = mProcessObservers.beginBroadcast();
3032        while (i > 0) {
3033            i--;
3034            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3035            if (observer != null) {
3036                try {
3037                    for (int j=0; j<N; j++) {
3038                        ProcessChangeItem item = mActiveProcessChanges[j];
3039                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3040                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3041                                    + item.pid + " uid=" + item.uid + ": "
3042                                    + item.foregroundActivities);
3043                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3044                                    item.foregroundActivities);
3045                        }
3046                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3047                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3048                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3049                            observer.onImportanceChanged(item.pid, item.uid,
3050                                    item.importance);
3051                        }
3052                    }
3053                } catch (RemoteException e) {
3054                }
3055            }
3056        }
3057        mProcessObservers.finishBroadcast();
3058    }
3059
3060    private void dispatchProcessDied(int pid, int uid) {
3061        int i = mProcessObservers.beginBroadcast();
3062        while (i > 0) {
3063            i--;
3064            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3065            if (observer != null) {
3066                try {
3067                    observer.onProcessDied(pid, uid);
3068                } catch (RemoteException e) {
3069                }
3070            }
3071        }
3072        mProcessObservers.finishBroadcast();
3073    }
3074
3075    final void doPendingActivityLaunchesLocked(boolean doResume) {
3076        final int N = mPendingActivityLaunches.size();
3077        if (N <= 0) {
3078            return;
3079        }
3080        for (int i=0; i<N; i++) {
3081            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3082            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3083                    doResume && i == (N-1), null);
3084        }
3085        mPendingActivityLaunches.clear();
3086    }
3087
3088    @Override
3089    public final int startActivity(IApplicationThread caller, String callingPackage,
3090            Intent intent, String resolvedType, IBinder resultTo,
3091            String resultWho, int requestCode, int startFlags,
3092            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3093        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3094                resultWho, requestCode,
3095                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3096    }
3097
3098    @Override
3099    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3100            Intent intent, String resolvedType, IBinder resultTo,
3101            String resultWho, int requestCode, int startFlags,
3102            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3103        enforceNotIsolatedCaller("startActivity");
3104        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3105                false, true, "startActivity", null);
3106        // TODO: Switch to user app stacks here.
3107        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3108                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3109                null, null, options, userId);
3110    }
3111
3112    @Override
3113    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3114            Intent intent, String resolvedType, IBinder resultTo,
3115            String resultWho, int requestCode, int startFlags, String profileFile,
3116            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3117        enforceNotIsolatedCaller("startActivityAndWait");
3118        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3119                false, true, "startActivityAndWait", null);
3120        WaitResult res = new WaitResult();
3121        // TODO: Switch to user app stacks here.
3122        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3123                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3124                res, null, options, UserHandle.getCallingUserId());
3125        return res;
3126    }
3127
3128    @Override
3129    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3130            Intent intent, String resolvedType, IBinder resultTo,
3131            String resultWho, int requestCode, int startFlags, Configuration config,
3132            Bundle options, int userId) {
3133        enforceNotIsolatedCaller("startActivityWithConfig");
3134        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3135                false, true, "startActivityWithConfig", null);
3136        // TODO: Switch to user app stacks here.
3137        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3138                resolvedType, resultTo, resultWho, requestCode, startFlags,
3139                null, null, null, config, options, userId);
3140        return ret;
3141    }
3142
3143    @Override
3144    public int startActivityIntentSender(IApplicationThread caller,
3145            IntentSender intent, Intent fillInIntent, String resolvedType,
3146            IBinder resultTo, String resultWho, int requestCode,
3147            int flagsMask, int flagsValues, Bundle options) {
3148        enforceNotIsolatedCaller("startActivityIntentSender");
3149        // Refuse possible leaked file descriptors
3150        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3151            throw new IllegalArgumentException("File descriptors passed in Intent");
3152        }
3153
3154        IIntentSender sender = intent.getTarget();
3155        if (!(sender instanceof PendingIntentRecord)) {
3156            throw new IllegalArgumentException("Bad PendingIntent object");
3157        }
3158
3159        PendingIntentRecord pir = (PendingIntentRecord)sender;
3160
3161        synchronized (this) {
3162            // If this is coming from the currently resumed activity, it is
3163            // effectively saying that app switches are allowed at this point.
3164            final ActivityStack stack = getFocusedStack();
3165            if (stack.mResumedActivity != null &&
3166                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3167                mAppSwitchesAllowedTime = 0;
3168            }
3169        }
3170        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3171                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
3172        return ret;
3173    }
3174
3175    @Override
3176    public boolean startNextMatchingActivity(IBinder callingActivity,
3177            Intent intent, Bundle options) {
3178        // Refuse possible leaked file descriptors
3179        if (intent != null && intent.hasFileDescriptors() == true) {
3180            throw new IllegalArgumentException("File descriptors passed in Intent");
3181        }
3182
3183        synchronized (this) {
3184            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3185            if (r == null) {
3186                ActivityOptions.abort(options);
3187                return false;
3188            }
3189            if (r.app == null || r.app.thread == null) {
3190                // The caller is not running...  d'oh!
3191                ActivityOptions.abort(options);
3192                return false;
3193            }
3194            intent = new Intent(intent);
3195            // The caller is not allowed to change the data.
3196            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3197            // And we are resetting to find the next component...
3198            intent.setComponent(null);
3199
3200            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3201
3202            ActivityInfo aInfo = null;
3203            try {
3204                List<ResolveInfo> resolves =
3205                    AppGlobals.getPackageManager().queryIntentActivities(
3206                            intent, r.resolvedType,
3207                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3208                            UserHandle.getCallingUserId());
3209
3210                // Look for the original activity in the list...
3211                final int N = resolves != null ? resolves.size() : 0;
3212                for (int i=0; i<N; i++) {
3213                    ResolveInfo rInfo = resolves.get(i);
3214                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3215                            && rInfo.activityInfo.name.equals(r.info.name)) {
3216                        // We found the current one...  the next matching is
3217                        // after it.
3218                        i++;
3219                        if (i<N) {
3220                            aInfo = resolves.get(i).activityInfo;
3221                        }
3222                        if (debug) {
3223                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3224                                    + "/" + r.info.name);
3225                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3226                                    + "/" + aInfo.name);
3227                        }
3228                        break;
3229                    }
3230                }
3231            } catch (RemoteException e) {
3232            }
3233
3234            if (aInfo == null) {
3235                // Nobody who is next!
3236                ActivityOptions.abort(options);
3237                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3238                return false;
3239            }
3240
3241            intent.setComponent(new ComponentName(
3242                    aInfo.applicationInfo.packageName, aInfo.name));
3243            intent.setFlags(intent.getFlags()&~(
3244                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3245                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3246                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3247                    Intent.FLAG_ACTIVITY_NEW_TASK));
3248
3249            // Okay now we need to start the new activity, replacing the
3250            // currently running activity.  This is a little tricky because
3251            // we want to start the new one as if the current one is finished,
3252            // but not finish the current one first so that there is no flicker.
3253            // And thus...
3254            final boolean wasFinishing = r.finishing;
3255            r.finishing = true;
3256
3257            // Propagate reply information over to the new activity.
3258            final ActivityRecord resultTo = r.resultTo;
3259            final String resultWho = r.resultWho;
3260            final int requestCode = r.requestCode;
3261            r.resultTo = null;
3262            if (resultTo != null) {
3263                resultTo.removeResultsLocked(r, resultWho, requestCode);
3264            }
3265
3266            final long origId = Binder.clearCallingIdentity();
3267            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3268                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3269                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3270                    options, false, null);
3271            Binder.restoreCallingIdentity(origId);
3272
3273            r.finishing = wasFinishing;
3274            if (res != ActivityManager.START_SUCCESS) {
3275                return false;
3276            }
3277            return true;
3278        }
3279    }
3280
3281    final int startActivityInPackage(int uid, String callingPackage,
3282            Intent intent, String resolvedType, IBinder resultTo,
3283            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
3284
3285        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3286                false, true, "startActivityInPackage", null);
3287
3288        // TODO: Switch to user app stacks here.
3289        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3290                resultTo, resultWho, requestCode, startFlags,
3291                null, null, null, null, options, userId);
3292        return ret;
3293    }
3294
3295    @Override
3296    public final int startActivities(IApplicationThread caller, String callingPackage,
3297            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3298            int userId) {
3299        enforceNotIsolatedCaller("startActivities");
3300        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3301                false, true, "startActivity", null);
3302        // TODO: Switch to user app stacks here.
3303        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3304                resolvedTypes, resultTo, options, userId);
3305        return ret;
3306    }
3307
3308    final int startActivitiesInPackage(int uid, String callingPackage,
3309            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3310            Bundle options, int userId) {
3311
3312        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3313                false, true, "startActivityInPackage", null);
3314        // TODO: Switch to user app stacks here.
3315        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3316                resultTo, options, userId);
3317        return ret;
3318    }
3319
3320    final void addRecentTaskLocked(TaskRecord task) {
3321        int N = mRecentTasks.size();
3322        // Quick case: check if the top-most recent task is the same.
3323        if (N > 0 && mRecentTasks.get(0) == task) {
3324            return;
3325        }
3326        // Remove any existing entries that are the same kind of task.
3327        for (int i=0; i<N; i++) {
3328            TaskRecord tr = mRecentTasks.get(i);
3329            if (task.userId == tr.userId
3330                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3331                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3332                tr.disposeThumbnail();
3333                mRecentTasks.remove(i);
3334                i--;
3335                N--;
3336                if (task.intent == null) {
3337                    // If the new recent task we are adding is not fully
3338                    // specified, then replace it with the existing recent task.
3339                    task = tr;
3340                }
3341            }
3342        }
3343        if (N >= MAX_RECENT_TASKS) {
3344            mRecentTasks.remove(N-1).disposeThumbnail();
3345        }
3346        mRecentTasks.add(0, task);
3347    }
3348
3349    @Override
3350    public void reportActivityFullyDrawn(IBinder token) {
3351        synchronized (this) {
3352            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3353            if (r == null) {
3354                return;
3355            }
3356            r.reportFullyDrawnLocked();
3357        }
3358    }
3359
3360    @Override
3361    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3362        synchronized (this) {
3363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3364            if (r == null) {
3365                return;
3366            }
3367            final long origId = Binder.clearCallingIdentity();
3368            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3369            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3370                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3371            if (config != null) {
3372                r.frozenBeforeDestroy = true;
3373                if (!updateConfigurationLocked(config, r, false, false)) {
3374                    mStackSupervisor.resumeTopActivitiesLocked();
3375                }
3376            }
3377            Binder.restoreCallingIdentity(origId);
3378        }
3379    }
3380
3381    @Override
3382    public int getRequestedOrientation(IBinder token) {
3383        synchronized (this) {
3384            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3385            if (r == null) {
3386                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3387            }
3388            return mWindowManager.getAppOrientation(r.appToken);
3389        }
3390    }
3391
3392    /**
3393     * This is the internal entry point for handling Activity.finish().
3394     *
3395     * @param token The Binder token referencing the Activity we want to finish.
3396     * @param resultCode Result code, if any, from this Activity.
3397     * @param resultData Result data (Intent), if any, from this Activity.
3398     *
3399     * @return Returns true if the activity successfully finished, or false if it is still running.
3400     */
3401    @Override
3402    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3403        // Refuse possible leaked file descriptors
3404        if (resultData != null && resultData.hasFileDescriptors() == true) {
3405            throw new IllegalArgumentException("File descriptors passed in Intent");
3406        }
3407
3408        synchronized(this) {
3409            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3410            if (r == null) {
3411                return true;
3412            }
3413            if (mController != null) {
3414                // Find the first activity that is not finishing.
3415                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3416                if (next != null) {
3417                    // ask watcher if this is allowed
3418                    boolean resumeOK = true;
3419                    try {
3420                        resumeOK = mController.activityResuming(next.packageName);
3421                    } catch (RemoteException e) {
3422                        mController = null;
3423                        Watchdog.getInstance().setActivityController(null);
3424                    }
3425
3426                    if (!resumeOK) {
3427                        return false;
3428                    }
3429                }
3430            }
3431            final long origId = Binder.clearCallingIdentity();
3432            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3433                    resultData, "app-request", true);
3434            Binder.restoreCallingIdentity(origId);
3435            return res;
3436        }
3437    }
3438
3439    @Override
3440    public final void finishHeavyWeightApp() {
3441        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3442                != PackageManager.PERMISSION_GRANTED) {
3443            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3444                    + Binder.getCallingPid()
3445                    + ", uid=" + Binder.getCallingUid()
3446                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3447            Slog.w(TAG, msg);
3448            throw new SecurityException(msg);
3449        }
3450
3451        synchronized(this) {
3452            if (mHeavyWeightProcess == null) {
3453                return;
3454            }
3455
3456            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3457                    mHeavyWeightProcess.activities);
3458            for (int i=0; i<activities.size(); i++) {
3459                ActivityRecord r = activities.get(i);
3460                if (!r.finishing) {
3461                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3462                            null, "finish-heavy", true);
3463                }
3464            }
3465
3466            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3467                    mHeavyWeightProcess.userId, 0));
3468            mHeavyWeightProcess = null;
3469        }
3470    }
3471
3472    @Override
3473    public void crashApplication(int uid, int initialPid, String packageName,
3474            String message) {
3475        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3476                != PackageManager.PERMISSION_GRANTED) {
3477            String msg = "Permission Denial: crashApplication() from pid="
3478                    + Binder.getCallingPid()
3479                    + ", uid=" + Binder.getCallingUid()
3480                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3481            Slog.w(TAG, msg);
3482            throw new SecurityException(msg);
3483        }
3484
3485        synchronized(this) {
3486            ProcessRecord proc = null;
3487
3488            // Figure out which process to kill.  We don't trust that initialPid
3489            // still has any relation to current pids, so must scan through the
3490            // list.
3491            synchronized (mPidsSelfLocked) {
3492                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3493                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3494                    if (p.uid != uid) {
3495                        continue;
3496                    }
3497                    if (p.pid == initialPid) {
3498                        proc = p;
3499                        break;
3500                    }
3501                    if (p.pkgList.containsKey(packageName)) {
3502                        proc = p;
3503                    }
3504                }
3505            }
3506
3507            if (proc == null) {
3508                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3509                        + " initialPid=" + initialPid
3510                        + " packageName=" + packageName);
3511                return;
3512            }
3513
3514            if (proc.thread != null) {
3515                if (proc.pid == Process.myPid()) {
3516                    Log.w(TAG, "crashApplication: trying to crash self!");
3517                    return;
3518                }
3519                long ident = Binder.clearCallingIdentity();
3520                try {
3521                    proc.thread.scheduleCrash(message);
3522                } catch (RemoteException e) {
3523                }
3524                Binder.restoreCallingIdentity(ident);
3525            }
3526        }
3527    }
3528
3529    @Override
3530    public final void finishSubActivity(IBinder token, String resultWho,
3531            int requestCode) {
3532        synchronized(this) {
3533            final long origId = Binder.clearCallingIdentity();
3534            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3535            if (r != null) {
3536                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3537            }
3538            Binder.restoreCallingIdentity(origId);
3539        }
3540    }
3541
3542    @Override
3543    public boolean finishActivityAffinity(IBinder token) {
3544        synchronized(this) {
3545            final long origId = Binder.clearCallingIdentity();
3546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3547            boolean res = false;
3548            if (r != null) {
3549                res = r.task.stack.finishActivityAffinityLocked(r);
3550            }
3551            Binder.restoreCallingIdentity(origId);
3552            return res;
3553        }
3554    }
3555
3556    @Override
3557    public boolean willActivityBeVisible(IBinder token) {
3558        synchronized(this) {
3559            ActivityStack stack = ActivityRecord.getStackLocked(token);
3560            if (stack != null) {
3561                return stack.willActivityBeVisibleLocked(token);
3562            }
3563            return false;
3564        }
3565    }
3566
3567    @Override
3568    public void overridePendingTransition(IBinder token, String packageName,
3569            int enterAnim, int exitAnim) {
3570        synchronized(this) {
3571            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3572            if (self == null) {
3573                return;
3574            }
3575
3576            final long origId = Binder.clearCallingIdentity();
3577
3578            if (self.state == ActivityState.RESUMED
3579                    || self.state == ActivityState.PAUSING) {
3580                mWindowManager.overridePendingAppTransition(packageName,
3581                        enterAnim, exitAnim, null);
3582            }
3583
3584            Binder.restoreCallingIdentity(origId);
3585        }
3586    }
3587
3588    /**
3589     * Main function for removing an existing process from the activity manager
3590     * as a result of that process going away.  Clears out all connections
3591     * to the process.
3592     */
3593    private final void handleAppDiedLocked(ProcessRecord app,
3594            boolean restarting, boolean allowRestart) {
3595        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3596        if (!restarting) {
3597            removeLruProcessLocked(app);
3598        }
3599
3600        if (mProfileProc == app) {
3601            clearProfilerLocked();
3602        }
3603
3604        // Remove this application's activities from active lists.
3605        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3606
3607        app.activities.clear();
3608
3609        if (app.instrumentationClass != null) {
3610            Slog.w(TAG, "Crash of app " + app.processName
3611                  + " running instrumentation " + app.instrumentationClass);
3612            Bundle info = new Bundle();
3613            info.putString("shortMsg", "Process crashed.");
3614            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3615        }
3616
3617        if (!restarting) {
3618            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3619                // If there was nothing to resume, and we are not already
3620                // restarting this process, but there is a visible activity that
3621                // is hosted by the process...  then make sure all visible
3622                // activities are running, taking care of restarting this
3623                // process.
3624                if (hasVisibleActivities) {
3625                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3626                }
3627            }
3628        }
3629    }
3630
3631    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3632        IBinder threadBinder = thread.asBinder();
3633        // Find the application record.
3634        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3635            ProcessRecord rec = mLruProcesses.get(i);
3636            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3637                return i;
3638            }
3639        }
3640        return -1;
3641    }
3642
3643    final ProcessRecord getRecordForAppLocked(
3644            IApplicationThread thread) {
3645        if (thread == null) {
3646            return null;
3647        }
3648
3649        int appIndex = getLRURecordIndexForAppLocked(thread);
3650        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3651    }
3652
3653    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3654        // If there are no longer any background processes running,
3655        // and the app that died was not running instrumentation,
3656        // then tell everyone we are now low on memory.
3657        boolean haveBg = false;
3658        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3659            ProcessRecord rec = mLruProcesses.get(i);
3660            if (rec.thread != null
3661                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3662                haveBg = true;
3663                break;
3664            }
3665        }
3666
3667        if (!haveBg) {
3668            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3669            if (doReport) {
3670                long now = SystemClock.uptimeMillis();
3671                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3672                    doReport = false;
3673                } else {
3674                    mLastMemUsageReportTime = now;
3675                }
3676            }
3677            final ArrayList<ProcessMemInfo> memInfos
3678                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3679            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3680            long now = SystemClock.uptimeMillis();
3681            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3682                ProcessRecord rec = mLruProcesses.get(i);
3683                if (rec == dyingProc || rec.thread == null) {
3684                    continue;
3685                }
3686                if (doReport) {
3687                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3688                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3689                }
3690                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3691                    // The low memory report is overriding any current
3692                    // state for a GC request.  Make sure to do
3693                    // heavy/important/visible/foreground processes first.
3694                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3695                        rec.lastRequestedGc = 0;
3696                    } else {
3697                        rec.lastRequestedGc = rec.lastLowMemory;
3698                    }
3699                    rec.reportLowMemory = true;
3700                    rec.lastLowMemory = now;
3701                    mProcessesToGc.remove(rec);
3702                    addProcessToGcListLocked(rec);
3703                }
3704            }
3705            if (doReport) {
3706                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3707                mHandler.sendMessage(msg);
3708            }
3709            scheduleAppGcsLocked();
3710        }
3711    }
3712
3713    final void appDiedLocked(ProcessRecord app, int pid,
3714            IApplicationThread thread) {
3715
3716        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3717        synchronized (stats) {
3718            stats.noteProcessDiedLocked(app.info.uid, pid);
3719        }
3720
3721        // Clean up already done if the process has been re-started.
3722        if (app.pid == pid && app.thread != null &&
3723                app.thread.asBinder() == thread.asBinder()) {
3724            boolean doLowMem = app.instrumentationClass == null;
3725            boolean doOomAdj = doLowMem;
3726            if (!app.killedByAm) {
3727                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3728                        + ") has died.");
3729                mAllowLowerMemLevel = true;
3730            } else {
3731                // Note that we always want to do oom adj to update our state with the
3732                // new number of procs.
3733                mAllowLowerMemLevel = false;
3734                doLowMem = false;
3735            }
3736            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3737            if (DEBUG_CLEANUP) Slog.v(
3738                TAG, "Dying app: " + app + ", pid: " + pid
3739                + ", thread: " + thread.asBinder());
3740            handleAppDiedLocked(app, false, true);
3741
3742            if (doOomAdj) {
3743                updateOomAdjLocked();
3744            }
3745            if (doLowMem) {
3746                doLowMemReportIfNeededLocked(app);
3747            }
3748        } else if (app.pid != pid) {
3749            // A new process has already been started.
3750            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3751                    + ") has died and restarted (pid " + app.pid + ").");
3752            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3753        } else if (DEBUG_PROCESSES) {
3754            Slog.d(TAG, "Received spurious death notification for thread "
3755                    + thread.asBinder());
3756        }
3757    }
3758
3759    /**
3760     * If a stack trace dump file is configured, dump process stack traces.
3761     * @param clearTraces causes the dump file to be erased prior to the new
3762     *    traces being written, if true; when false, the new traces will be
3763     *    appended to any existing file content.
3764     * @param firstPids of dalvik VM processes to dump stack traces for first
3765     * @param lastPids of dalvik VM processes to dump stack traces for last
3766     * @param nativeProcs optional list of native process names to dump stack crawls
3767     * @return file containing stack traces, or null if no dump file is configured
3768     */
3769    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3770            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3771        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3772        if (tracesPath == null || tracesPath.length() == 0) {
3773            return null;
3774        }
3775
3776        File tracesFile = new File(tracesPath);
3777        try {
3778            File tracesDir = tracesFile.getParentFile();
3779            if (!tracesDir.exists()) {
3780                tracesFile.mkdirs();
3781                if (!SELinux.restorecon(tracesDir)) {
3782                    return null;
3783                }
3784            }
3785            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3786
3787            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3788            tracesFile.createNewFile();
3789            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3790        } catch (IOException e) {
3791            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3792            return null;
3793        }
3794
3795        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3796        return tracesFile;
3797    }
3798
3799    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3800            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3801        // Use a FileObserver to detect when traces finish writing.
3802        // The order of traces is considered important to maintain for legibility.
3803        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3804            @Override
3805            public synchronized void onEvent(int event, String path) { notify(); }
3806        };
3807
3808        try {
3809            observer.startWatching();
3810
3811            // First collect all of the stacks of the most important pids.
3812            if (firstPids != null) {
3813                try {
3814                    int num = firstPids.size();
3815                    for (int i = 0; i < num; i++) {
3816                        synchronized (observer) {
3817                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3818                            observer.wait(200);  // Wait for write-close, give up after 200msec
3819                        }
3820                    }
3821                } catch (InterruptedException e) {
3822                    Log.wtf(TAG, e);
3823                }
3824            }
3825
3826            // Next collect the stacks of the native pids
3827            if (nativeProcs != null) {
3828                int[] pids = Process.getPidsForCommands(nativeProcs);
3829                if (pids != null) {
3830                    for (int pid : pids) {
3831                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3832                    }
3833                }
3834            }
3835
3836            // Lastly, measure CPU usage.
3837            if (processCpuTracker != null) {
3838                processCpuTracker.init();
3839                System.gc();
3840                processCpuTracker.update();
3841                try {
3842                    synchronized (processCpuTracker) {
3843                        processCpuTracker.wait(500); // measure over 1/2 second.
3844                    }
3845                } catch (InterruptedException e) {
3846                }
3847                processCpuTracker.update();
3848
3849                // We'll take the stack crawls of just the top apps using CPU.
3850                final int N = processCpuTracker.countWorkingStats();
3851                int numProcs = 0;
3852                for (int i=0; i<N && numProcs<5; i++) {
3853                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3854                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3855                        numProcs++;
3856                        try {
3857                            synchronized (observer) {
3858                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3859                                observer.wait(200);  // Wait for write-close, give up after 200msec
3860                            }
3861                        } catch (InterruptedException e) {
3862                            Log.wtf(TAG, e);
3863                        }
3864
3865                    }
3866                }
3867            }
3868        } finally {
3869            observer.stopWatching();
3870        }
3871    }
3872
3873    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3874        if (true || IS_USER_BUILD) {
3875            return;
3876        }
3877        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3878        if (tracesPath == null || tracesPath.length() == 0) {
3879            return;
3880        }
3881
3882        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3883        StrictMode.allowThreadDiskWrites();
3884        try {
3885            final File tracesFile = new File(tracesPath);
3886            final File tracesDir = tracesFile.getParentFile();
3887            final File tracesTmp = new File(tracesDir, "__tmp__");
3888            try {
3889                if (!tracesDir.exists()) {
3890                    tracesFile.mkdirs();
3891                    if (!SELinux.restorecon(tracesDir.getPath())) {
3892                        return;
3893                    }
3894                }
3895                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3896
3897                if (tracesFile.exists()) {
3898                    tracesTmp.delete();
3899                    tracesFile.renameTo(tracesTmp);
3900                }
3901                StringBuilder sb = new StringBuilder();
3902                Time tobj = new Time();
3903                tobj.set(System.currentTimeMillis());
3904                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3905                sb.append(": ");
3906                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3907                sb.append(" since ");
3908                sb.append(msg);
3909                FileOutputStream fos = new FileOutputStream(tracesFile);
3910                fos.write(sb.toString().getBytes());
3911                if (app == null) {
3912                    fos.write("\n*** No application process!".getBytes());
3913                }
3914                fos.close();
3915                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3916            } catch (IOException e) {
3917                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3918                return;
3919            }
3920
3921            if (app != null) {
3922                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3923                firstPids.add(app.pid);
3924                dumpStackTraces(tracesPath, firstPids, null, null, null);
3925            }
3926
3927            File lastTracesFile = null;
3928            File curTracesFile = null;
3929            for (int i=9; i>=0; i--) {
3930                String name = String.format(Locale.US, "slow%02d.txt", i);
3931                curTracesFile = new File(tracesDir, name);
3932                if (curTracesFile.exists()) {
3933                    if (lastTracesFile != null) {
3934                        curTracesFile.renameTo(lastTracesFile);
3935                    } else {
3936                        curTracesFile.delete();
3937                    }
3938                }
3939                lastTracesFile = curTracesFile;
3940            }
3941            tracesFile.renameTo(curTracesFile);
3942            if (tracesTmp.exists()) {
3943                tracesTmp.renameTo(tracesFile);
3944            }
3945        } finally {
3946            StrictMode.setThreadPolicy(oldPolicy);
3947        }
3948    }
3949
3950    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3951            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3952        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3953        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3954
3955        if (mController != null) {
3956            try {
3957                // 0 == continue, -1 = kill process immediately
3958                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3959                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3960            } catch (RemoteException e) {
3961                mController = null;
3962                Watchdog.getInstance().setActivityController(null);
3963            }
3964        }
3965
3966        long anrTime = SystemClock.uptimeMillis();
3967        if (MONITOR_CPU_USAGE) {
3968            updateCpuStatsNow();
3969        }
3970
3971        synchronized (this) {
3972            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3973            if (mShuttingDown) {
3974                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3975                return;
3976            } else if (app.notResponding) {
3977                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3978                return;
3979            } else if (app.crashing) {
3980                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3981                return;
3982            }
3983
3984            // In case we come through here for the same app before completing
3985            // this one, mark as anring now so we will bail out.
3986            app.notResponding = true;
3987
3988            // Log the ANR to the event log.
3989            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3990                    app.processName, app.info.flags, annotation);
3991
3992            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3993            firstPids.add(app.pid);
3994
3995            int parentPid = app.pid;
3996            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3997            if (parentPid != app.pid) firstPids.add(parentPid);
3998
3999            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4000
4001            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4002                ProcessRecord r = mLruProcesses.get(i);
4003                if (r != null && r.thread != null) {
4004                    int pid = r.pid;
4005                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4006                        if (r.persistent) {
4007                            firstPids.add(pid);
4008                        } else {
4009                            lastPids.put(pid, Boolean.TRUE);
4010                        }
4011                    }
4012                }
4013            }
4014        }
4015
4016        // Log the ANR to the main log.
4017        StringBuilder info = new StringBuilder();
4018        info.setLength(0);
4019        info.append("ANR in ").append(app.processName);
4020        if (activity != null && activity.shortComponentName != null) {
4021            info.append(" (").append(activity.shortComponentName).append(")");
4022        }
4023        info.append("\n");
4024        info.append("PID: ").append(app.pid).append("\n");
4025        if (annotation != null) {
4026            info.append("Reason: ").append(annotation).append("\n");
4027        }
4028        if (parent != null && parent != activity) {
4029            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4030        }
4031
4032        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4033
4034        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4035                NATIVE_STACKS_OF_INTEREST);
4036
4037        String cpuInfo = null;
4038        if (MONITOR_CPU_USAGE) {
4039            updateCpuStatsNow();
4040            synchronized (mProcessCpuThread) {
4041                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4042            }
4043            info.append(processCpuTracker.printCurrentLoad());
4044            info.append(cpuInfo);
4045        }
4046
4047        info.append(processCpuTracker.printCurrentState(anrTime));
4048
4049        Slog.e(TAG, info.toString());
4050        if (tracesFile == null) {
4051            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4052            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4053        }
4054
4055        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4056                cpuInfo, tracesFile, null);
4057
4058        if (mController != null) {
4059            try {
4060                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4061                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4062                if (res != 0) {
4063                    if (res < 0 && app.pid != MY_PID) {
4064                        Process.killProcess(app.pid);
4065                    } else {
4066                        synchronized (this) {
4067                            mServices.scheduleServiceTimeoutLocked(app);
4068                        }
4069                    }
4070                    return;
4071                }
4072            } catch (RemoteException e) {
4073                mController = null;
4074                Watchdog.getInstance().setActivityController(null);
4075            }
4076        }
4077
4078        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4079        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4080                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4081
4082        synchronized (this) {
4083            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4084                killUnneededProcessLocked(app, "background ANR");
4085                return;
4086            }
4087
4088            // Set the app's notResponding state, and look up the errorReportReceiver
4089            makeAppNotRespondingLocked(app,
4090                    activity != null ? activity.shortComponentName : null,
4091                    annotation != null ? "ANR " + annotation : "ANR",
4092                    info.toString());
4093
4094            // Bring up the infamous App Not Responding dialog
4095            Message msg = Message.obtain();
4096            HashMap<String, Object> map = new HashMap<String, Object>();
4097            msg.what = SHOW_NOT_RESPONDING_MSG;
4098            msg.obj = map;
4099            msg.arg1 = aboveSystem ? 1 : 0;
4100            map.put("app", app);
4101            if (activity != null) {
4102                map.put("activity", activity);
4103            }
4104
4105            mHandler.sendMessage(msg);
4106        }
4107    }
4108
4109    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4110        if (!mLaunchWarningShown) {
4111            mLaunchWarningShown = true;
4112            mHandler.post(new Runnable() {
4113                @Override
4114                public void run() {
4115                    synchronized (ActivityManagerService.this) {
4116                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4117                        d.show();
4118                        mHandler.postDelayed(new Runnable() {
4119                            @Override
4120                            public void run() {
4121                                synchronized (ActivityManagerService.this) {
4122                                    d.dismiss();
4123                                    mLaunchWarningShown = false;
4124                                }
4125                            }
4126                        }, 4000);
4127                    }
4128                }
4129            });
4130        }
4131    }
4132
4133    @Override
4134    public boolean clearApplicationUserData(final String packageName,
4135            final IPackageDataObserver observer, int userId) {
4136        enforceNotIsolatedCaller("clearApplicationUserData");
4137        int uid = Binder.getCallingUid();
4138        int pid = Binder.getCallingPid();
4139        userId = handleIncomingUser(pid, uid,
4140                userId, false, true, "clearApplicationUserData", null);
4141        long callingId = Binder.clearCallingIdentity();
4142        try {
4143            IPackageManager pm = AppGlobals.getPackageManager();
4144            int pkgUid = -1;
4145            synchronized(this) {
4146                try {
4147                    pkgUid = pm.getPackageUid(packageName, userId);
4148                } catch (RemoteException e) {
4149                }
4150                if (pkgUid == -1) {
4151                    Slog.w(TAG, "Invalid packageName: " + packageName);
4152                    if (observer != null) {
4153                        try {
4154                            observer.onRemoveCompleted(packageName, false);
4155                        } catch (RemoteException e) {
4156                            Slog.i(TAG, "Observer no longer exists.");
4157                        }
4158                    }
4159                    return false;
4160                }
4161                if (uid == pkgUid || checkComponentPermission(
4162                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4163                        pid, uid, -1, true)
4164                        == PackageManager.PERMISSION_GRANTED) {
4165                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4166                } else {
4167                    throw new SecurityException("PID " + pid + " does not have permission "
4168                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4169                                    + " of package " + packageName);
4170                }
4171            }
4172
4173            try {
4174                // Clear application user data
4175                pm.clearApplicationUserData(packageName, observer, userId);
4176
4177                // Remove all permissions granted from/to this package
4178                removeUriPermissionsForPackageLocked(packageName, userId, true);
4179
4180                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4181                        Uri.fromParts("package", packageName, null));
4182                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4183                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4184                        null, null, 0, null, null, null, false, false, userId);
4185            } catch (RemoteException e) {
4186            }
4187        } finally {
4188            Binder.restoreCallingIdentity(callingId);
4189        }
4190        return true;
4191    }
4192
4193    @Override
4194    public void killBackgroundProcesses(final String packageName, int userId) {
4195        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4196                != PackageManager.PERMISSION_GRANTED &&
4197                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4198                        != PackageManager.PERMISSION_GRANTED) {
4199            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4200                    + Binder.getCallingPid()
4201                    + ", uid=" + Binder.getCallingUid()
4202                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4203            Slog.w(TAG, msg);
4204            throw new SecurityException(msg);
4205        }
4206
4207        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4208                userId, true, true, "killBackgroundProcesses", null);
4209        long callingId = Binder.clearCallingIdentity();
4210        try {
4211            IPackageManager pm = AppGlobals.getPackageManager();
4212            synchronized(this) {
4213                int appId = -1;
4214                try {
4215                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4216                } catch (RemoteException e) {
4217                }
4218                if (appId == -1) {
4219                    Slog.w(TAG, "Invalid packageName: " + packageName);
4220                    return;
4221                }
4222                killPackageProcessesLocked(packageName, appId, userId,
4223                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4224            }
4225        } finally {
4226            Binder.restoreCallingIdentity(callingId);
4227        }
4228    }
4229
4230    @Override
4231    public void killAllBackgroundProcesses() {
4232        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4233                != PackageManager.PERMISSION_GRANTED) {
4234            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4235                    + Binder.getCallingPid()
4236                    + ", uid=" + Binder.getCallingUid()
4237                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4238            Slog.w(TAG, msg);
4239            throw new SecurityException(msg);
4240        }
4241
4242        long callingId = Binder.clearCallingIdentity();
4243        try {
4244            synchronized(this) {
4245                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4246                final int NP = mProcessNames.getMap().size();
4247                for (int ip=0; ip<NP; ip++) {
4248                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4249                    final int NA = apps.size();
4250                    for (int ia=0; ia<NA; ia++) {
4251                        ProcessRecord app = apps.valueAt(ia);
4252                        if (app.persistent) {
4253                            // we don't kill persistent processes
4254                            continue;
4255                        }
4256                        if (app.removed) {
4257                            procs.add(app);
4258                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4259                            app.removed = true;
4260                            procs.add(app);
4261                        }
4262                    }
4263                }
4264
4265                int N = procs.size();
4266                for (int i=0; i<N; i++) {
4267                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4268                }
4269                mAllowLowerMemLevel = true;
4270                updateOomAdjLocked();
4271                doLowMemReportIfNeededLocked(null);
4272            }
4273        } finally {
4274            Binder.restoreCallingIdentity(callingId);
4275        }
4276    }
4277
4278    @Override
4279    public void forceStopPackage(final String packageName, int userId) {
4280        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4281                != PackageManager.PERMISSION_GRANTED) {
4282            String msg = "Permission Denial: forceStopPackage() from pid="
4283                    + Binder.getCallingPid()
4284                    + ", uid=" + Binder.getCallingUid()
4285                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4286            Slog.w(TAG, msg);
4287            throw new SecurityException(msg);
4288        }
4289        final int callingPid = Binder.getCallingPid();
4290        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4291                userId, true, true, "forceStopPackage", null);
4292        long callingId = Binder.clearCallingIdentity();
4293        try {
4294            IPackageManager pm = AppGlobals.getPackageManager();
4295            synchronized(this) {
4296                int[] users = userId == UserHandle.USER_ALL
4297                        ? getUsersLocked() : new int[] { userId };
4298                for (int user : users) {
4299                    int pkgUid = -1;
4300                    try {
4301                        pkgUid = pm.getPackageUid(packageName, user);
4302                    } catch (RemoteException e) {
4303                    }
4304                    if (pkgUid == -1) {
4305                        Slog.w(TAG, "Invalid packageName: " + packageName);
4306                        continue;
4307                    }
4308                    try {
4309                        pm.setPackageStoppedState(packageName, true, user);
4310                    } catch (RemoteException e) {
4311                    } catch (IllegalArgumentException e) {
4312                        Slog.w(TAG, "Failed trying to unstop package "
4313                                + packageName + ": " + e);
4314                    }
4315                    if (isUserRunningLocked(user, false)) {
4316                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4317                    }
4318                }
4319            }
4320        } finally {
4321            Binder.restoreCallingIdentity(callingId);
4322        }
4323    }
4324
4325    /*
4326     * The pkg name and app id have to be specified.
4327     */
4328    @Override
4329    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4330        if (pkg == null) {
4331            return;
4332        }
4333        // Make sure the uid is valid.
4334        if (appid < 0) {
4335            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4336            return;
4337        }
4338        int callerUid = Binder.getCallingUid();
4339        // Only the system server can kill an application
4340        if (callerUid == Process.SYSTEM_UID) {
4341            // Post an aysnc message to kill the application
4342            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4343            msg.arg1 = appid;
4344            msg.arg2 = 0;
4345            Bundle bundle = new Bundle();
4346            bundle.putString("pkg", pkg);
4347            bundle.putString("reason", reason);
4348            msg.obj = bundle;
4349            mHandler.sendMessage(msg);
4350        } else {
4351            throw new SecurityException(callerUid + " cannot kill pkg: " +
4352                    pkg);
4353        }
4354    }
4355
4356    @Override
4357    public void closeSystemDialogs(String reason) {
4358        enforceNotIsolatedCaller("closeSystemDialogs");
4359
4360        final int pid = Binder.getCallingPid();
4361        final int uid = Binder.getCallingUid();
4362        final long origId = Binder.clearCallingIdentity();
4363        try {
4364            synchronized (this) {
4365                // Only allow this from foreground processes, so that background
4366                // applications can't abuse it to prevent system UI from being shown.
4367                if (uid >= Process.FIRST_APPLICATION_UID) {
4368                    ProcessRecord proc;
4369                    synchronized (mPidsSelfLocked) {
4370                        proc = mPidsSelfLocked.get(pid);
4371                    }
4372                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4373                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4374                                + " from background process " + proc);
4375                        return;
4376                    }
4377                }
4378                closeSystemDialogsLocked(reason);
4379            }
4380        } finally {
4381            Binder.restoreCallingIdentity(origId);
4382        }
4383    }
4384
4385    void closeSystemDialogsLocked(String reason) {
4386        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4387        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4388                | Intent.FLAG_RECEIVER_FOREGROUND);
4389        if (reason != null) {
4390            intent.putExtra("reason", reason);
4391        }
4392        mWindowManager.closeSystemDialogs(reason);
4393
4394        mStackSupervisor.closeSystemDialogsLocked();
4395
4396        broadcastIntentLocked(null, null, intent, null,
4397                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4398                Process.SYSTEM_UID, UserHandle.USER_ALL);
4399    }
4400
4401    @Override
4402    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4403        enforceNotIsolatedCaller("getProcessMemoryInfo");
4404        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4405        for (int i=pids.length-1; i>=0; i--) {
4406            ProcessRecord proc;
4407            int oomAdj;
4408            synchronized (this) {
4409                synchronized (mPidsSelfLocked) {
4410                    proc = mPidsSelfLocked.get(pids[i]);
4411                    oomAdj = proc != null ? proc.setAdj : 0;
4412                }
4413            }
4414            infos[i] = new Debug.MemoryInfo();
4415            Debug.getMemoryInfo(pids[i], infos[i]);
4416            if (proc != null) {
4417                synchronized (this) {
4418                    if (proc.thread != null && proc.setAdj == oomAdj) {
4419                        // Record this for posterity if the process has been stable.
4420                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4421                                infos[i].getTotalUss(), false, proc.pkgList);
4422                    }
4423                }
4424            }
4425        }
4426        return infos;
4427    }
4428
4429    @Override
4430    public long[] getProcessPss(int[] pids) {
4431        enforceNotIsolatedCaller("getProcessPss");
4432        long[] pss = new long[pids.length];
4433        for (int i=pids.length-1; i>=0; i--) {
4434            ProcessRecord proc;
4435            int oomAdj;
4436            synchronized (this) {
4437                synchronized (mPidsSelfLocked) {
4438                    proc = mPidsSelfLocked.get(pids[i]);
4439                    oomAdj = proc != null ? proc.setAdj : 0;
4440                }
4441            }
4442            long[] tmpUss = new long[1];
4443            pss[i] = Debug.getPss(pids[i], tmpUss);
4444            if (proc != null) {
4445                synchronized (this) {
4446                    if (proc.thread != null && proc.setAdj == oomAdj) {
4447                        // Record this for posterity if the process has been stable.
4448                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4449                    }
4450                }
4451            }
4452        }
4453        return pss;
4454    }
4455
4456    @Override
4457    public void killApplicationProcess(String processName, int uid) {
4458        if (processName == null) {
4459            return;
4460        }
4461
4462        int callerUid = Binder.getCallingUid();
4463        // Only the system server can kill an application
4464        if (callerUid == Process.SYSTEM_UID) {
4465            synchronized (this) {
4466                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4467                if (app != null && app.thread != null) {
4468                    try {
4469                        app.thread.scheduleSuicide();
4470                    } catch (RemoteException e) {
4471                        // If the other end already died, then our work here is done.
4472                    }
4473                } else {
4474                    Slog.w(TAG, "Process/uid not found attempting kill of "
4475                            + processName + " / " + uid);
4476                }
4477            }
4478        } else {
4479            throw new SecurityException(callerUid + " cannot kill app process: " +
4480                    processName);
4481        }
4482    }
4483
4484    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4485        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4486                false, true, false, UserHandle.getUserId(uid), reason);
4487        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4488                Uri.fromParts("package", packageName, null));
4489        if (!mProcessesReady) {
4490            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4491                    | Intent.FLAG_RECEIVER_FOREGROUND);
4492        }
4493        intent.putExtra(Intent.EXTRA_UID, uid);
4494        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4495        broadcastIntentLocked(null, null, intent,
4496                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4497                false, false,
4498                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4499    }
4500
4501    private void forceStopUserLocked(int userId, String reason) {
4502        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4503        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4504        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4505                | Intent.FLAG_RECEIVER_FOREGROUND);
4506        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4507        broadcastIntentLocked(null, null, intent,
4508                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4509                false, false,
4510                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4511    }
4512
4513    private final boolean killPackageProcessesLocked(String packageName, int appId,
4514            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4515            boolean doit, boolean evenPersistent, String reason) {
4516        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4517
4518        // Remove all processes this package may have touched: all with the
4519        // same UID (except for the system or root user), and all whose name
4520        // matches the package name.
4521        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4522        final int NP = mProcessNames.getMap().size();
4523        for (int ip=0; ip<NP; ip++) {
4524            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4525            final int NA = apps.size();
4526            for (int ia=0; ia<NA; ia++) {
4527                ProcessRecord app = apps.valueAt(ia);
4528                if (app.persistent && !evenPersistent) {
4529                    // we don't kill persistent processes
4530                    continue;
4531                }
4532                if (app.removed) {
4533                    if (doit) {
4534                        procs.add(app);
4535                    }
4536                    continue;
4537                }
4538
4539                // Skip process if it doesn't meet our oom adj requirement.
4540                if (app.setAdj < minOomAdj) {
4541                    continue;
4542                }
4543
4544                // If no package is specified, we call all processes under the
4545                // give user id.
4546                if (packageName == null) {
4547                    if (app.userId != userId) {
4548                        continue;
4549                    }
4550                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4551                        continue;
4552                    }
4553                // Package has been specified, we want to hit all processes
4554                // that match it.  We need to qualify this by the processes
4555                // that are running under the specified app and user ID.
4556                } else {
4557                    if (UserHandle.getAppId(app.uid) != appId) {
4558                        continue;
4559                    }
4560                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4561                        continue;
4562                    }
4563                    if (!app.pkgList.containsKey(packageName)) {
4564                        continue;
4565                    }
4566                }
4567
4568                // Process has passed all conditions, kill it!
4569                if (!doit) {
4570                    return true;
4571                }
4572                app.removed = true;
4573                procs.add(app);
4574            }
4575        }
4576
4577        int N = procs.size();
4578        for (int i=0; i<N; i++) {
4579            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4580        }
4581        updateOomAdjLocked();
4582        return N > 0;
4583    }
4584
4585    private final boolean forceStopPackageLocked(String name, int appId,
4586            boolean callerWillRestart, boolean purgeCache, boolean doit,
4587            boolean evenPersistent, int userId, String reason) {
4588        int i;
4589        int N;
4590
4591        if (userId == UserHandle.USER_ALL && name == null) {
4592            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4593        }
4594
4595        if (appId < 0 && name != null) {
4596            try {
4597                appId = UserHandle.getAppId(
4598                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4599            } catch (RemoteException e) {
4600            }
4601        }
4602
4603        if (doit) {
4604            if (name != null) {
4605                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4606                        + " user=" + userId + ": " + reason);
4607            } else {
4608                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4609            }
4610
4611            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4612            for (int ip=pmap.size()-1; ip>=0; ip--) {
4613                SparseArray<Long> ba = pmap.valueAt(ip);
4614                for (i=ba.size()-1; i>=0; i--) {
4615                    boolean remove = false;
4616                    final int entUid = ba.keyAt(i);
4617                    if (name != null) {
4618                        if (userId == UserHandle.USER_ALL) {
4619                            if (UserHandle.getAppId(entUid) == appId) {
4620                                remove = true;
4621                            }
4622                        } else {
4623                            if (entUid == UserHandle.getUid(userId, appId)) {
4624                                remove = true;
4625                            }
4626                        }
4627                    } else if (UserHandle.getUserId(entUid) == userId) {
4628                        remove = true;
4629                    }
4630                    if (remove) {
4631                        ba.removeAt(i);
4632                    }
4633                }
4634                if (ba.size() == 0) {
4635                    pmap.removeAt(ip);
4636                }
4637            }
4638        }
4639
4640        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4641                -100, callerWillRestart, true, doit, evenPersistent,
4642                name == null ? ("stop user " + userId) : ("stop " + name));
4643
4644        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4645            if (!doit) {
4646                return true;
4647            }
4648            didSomething = true;
4649        }
4650
4651        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4652            if (!doit) {
4653                return true;
4654            }
4655            didSomething = true;
4656        }
4657
4658        if (name == null) {
4659            // Remove all sticky broadcasts from this user.
4660            mStickyBroadcasts.remove(userId);
4661        }
4662
4663        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4664        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4665                userId, providers)) {
4666            if (!doit) {
4667                return true;
4668            }
4669            didSomething = true;
4670        }
4671        N = providers.size();
4672        for (i=0; i<N; i++) {
4673            removeDyingProviderLocked(null, providers.get(i), true);
4674        }
4675
4676        // Remove transient permissions granted from/to this package/user
4677        removeUriPermissionsForPackageLocked(name, userId, false);
4678
4679        if (name == null) {
4680            // Remove pending intents.  For now we only do this when force
4681            // stopping users, because we have some problems when doing this
4682            // for packages -- app widgets are not currently cleaned up for
4683            // such packages, so they can be left with bad pending intents.
4684            if (mIntentSenderRecords.size() > 0) {
4685                Iterator<WeakReference<PendingIntentRecord>> it
4686                        = mIntentSenderRecords.values().iterator();
4687                while (it.hasNext()) {
4688                    WeakReference<PendingIntentRecord> wpir = it.next();
4689                    if (wpir == null) {
4690                        it.remove();
4691                        continue;
4692                    }
4693                    PendingIntentRecord pir = wpir.get();
4694                    if (pir == null) {
4695                        it.remove();
4696                        continue;
4697                    }
4698                    if (name == null) {
4699                        // Stopping user, remove all objects for the user.
4700                        if (pir.key.userId != userId) {
4701                            // Not the same user, skip it.
4702                            continue;
4703                        }
4704                    } else {
4705                        if (UserHandle.getAppId(pir.uid) != appId) {
4706                            // Different app id, skip it.
4707                            continue;
4708                        }
4709                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4710                            // Different user, skip it.
4711                            continue;
4712                        }
4713                        if (!pir.key.packageName.equals(name)) {
4714                            // Different package, skip it.
4715                            continue;
4716                        }
4717                    }
4718                    if (!doit) {
4719                        return true;
4720                    }
4721                    didSomething = true;
4722                    it.remove();
4723                    pir.canceled = true;
4724                    if (pir.key.activity != null) {
4725                        pir.key.activity.pendingResults.remove(pir.ref);
4726                    }
4727                }
4728            }
4729        }
4730
4731        if (doit) {
4732            if (purgeCache && name != null) {
4733                AttributeCache ac = AttributeCache.instance();
4734                if (ac != null) {
4735                    ac.removePackage(name);
4736                }
4737            }
4738            if (mBooted) {
4739                mStackSupervisor.resumeTopActivitiesLocked();
4740                mStackSupervisor.scheduleIdleLocked();
4741            }
4742        }
4743
4744        return didSomething;
4745    }
4746
4747    private final boolean removeProcessLocked(ProcessRecord app,
4748            boolean callerWillRestart, boolean allowRestart, String reason) {
4749        final String name = app.processName;
4750        final int uid = app.uid;
4751        if (DEBUG_PROCESSES) Slog.d(
4752            TAG, "Force removing proc " + app.toShortString() + " (" + name
4753            + "/" + uid + ")");
4754
4755        mProcessNames.remove(name, uid);
4756        mIsolatedProcesses.remove(app.uid);
4757        if (mHeavyWeightProcess == app) {
4758            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4759                    mHeavyWeightProcess.userId, 0));
4760            mHeavyWeightProcess = null;
4761        }
4762        boolean needRestart = false;
4763        if (app.pid > 0 && app.pid != MY_PID) {
4764            int pid = app.pid;
4765            synchronized (mPidsSelfLocked) {
4766                mPidsSelfLocked.remove(pid);
4767                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4768            }
4769            killUnneededProcessLocked(app, reason);
4770            handleAppDiedLocked(app, true, allowRestart);
4771            removeLruProcessLocked(app);
4772
4773            if (app.persistent && !app.isolated) {
4774                if (!callerWillRestart) {
4775                    addAppLocked(app.info, false);
4776                } else {
4777                    needRestart = true;
4778                }
4779            }
4780        } else {
4781            mRemovedProcesses.add(app);
4782        }
4783
4784        return needRestart;
4785    }
4786
4787    private final void processStartTimedOutLocked(ProcessRecord app) {
4788        final int pid = app.pid;
4789        boolean gone = false;
4790        synchronized (mPidsSelfLocked) {
4791            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4792            if (knownApp != null && knownApp.thread == null) {
4793                mPidsSelfLocked.remove(pid);
4794                gone = true;
4795            }
4796        }
4797
4798        if (gone) {
4799            Slog.w(TAG, "Process " + app + " failed to attach");
4800            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4801                    pid, app.uid, app.processName);
4802            mProcessNames.remove(app.processName, app.uid);
4803            mIsolatedProcesses.remove(app.uid);
4804            if (mHeavyWeightProcess == app) {
4805                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4806                        mHeavyWeightProcess.userId, 0));
4807                mHeavyWeightProcess = null;
4808            }
4809            // Take care of any launching providers waiting for this process.
4810            checkAppInLaunchingProvidersLocked(app, true);
4811            // Take care of any services that are waiting for the process.
4812            mServices.processStartTimedOutLocked(app);
4813            killUnneededProcessLocked(app, "start timeout");
4814            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4815                Slog.w(TAG, "Unattached app died before backup, skipping");
4816                try {
4817                    IBackupManager bm = IBackupManager.Stub.asInterface(
4818                            ServiceManager.getService(Context.BACKUP_SERVICE));
4819                    bm.agentDisconnected(app.info.packageName);
4820                } catch (RemoteException e) {
4821                    // Can't happen; the backup manager is local
4822                }
4823            }
4824            if (isPendingBroadcastProcessLocked(pid)) {
4825                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4826                skipPendingBroadcastLocked(pid);
4827            }
4828        } else {
4829            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4830        }
4831    }
4832
4833    private final boolean attachApplicationLocked(IApplicationThread thread,
4834            int pid) {
4835
4836        // Find the application record that is being attached...  either via
4837        // the pid if we are running in multiple processes, or just pull the
4838        // next app record if we are emulating process with anonymous threads.
4839        ProcessRecord app;
4840        if (pid != MY_PID && pid >= 0) {
4841            synchronized (mPidsSelfLocked) {
4842                app = mPidsSelfLocked.get(pid);
4843            }
4844        } else {
4845            app = null;
4846        }
4847
4848        if (app == null) {
4849            Slog.w(TAG, "No pending application record for pid " + pid
4850                    + " (IApplicationThread " + thread + "); dropping process");
4851            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4852            if (pid > 0 && pid != MY_PID) {
4853                Process.killProcessQuiet(pid);
4854            } else {
4855                try {
4856                    thread.scheduleExit();
4857                } catch (Exception e) {
4858                    // Ignore exceptions.
4859                }
4860            }
4861            return false;
4862        }
4863
4864        // If this application record is still attached to a previous
4865        // process, clean it up now.
4866        if (app.thread != null) {
4867            handleAppDiedLocked(app, true, true);
4868        }
4869
4870        // Tell the process all about itself.
4871
4872        if (localLOGV) Slog.v(
4873                TAG, "Binding process pid " + pid + " to record " + app);
4874
4875        final String processName = app.processName;
4876        try {
4877            AppDeathRecipient adr = new AppDeathRecipient(
4878                    app, pid, thread);
4879            thread.asBinder().linkToDeath(adr, 0);
4880            app.deathRecipient = adr;
4881        } catch (RemoteException e) {
4882            app.resetPackageList(mProcessStats);
4883            startProcessLocked(app, "link fail", processName);
4884            return false;
4885        }
4886
4887        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4888
4889        app.makeActive(thread, mProcessStats);
4890        app.curAdj = app.setAdj = -100;
4891        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4892        app.forcingToForeground = null;
4893        app.foregroundServices = false;
4894        app.hasShownUi = false;
4895        app.debugging = false;
4896        app.cached = false;
4897
4898        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4899
4900        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4901        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4902
4903        if (!normalMode) {
4904            Slog.i(TAG, "Launching preboot mode app: " + app);
4905        }
4906
4907        if (localLOGV) Slog.v(
4908            TAG, "New app record " + app
4909            + " thread=" + thread.asBinder() + " pid=" + pid);
4910        try {
4911            int testMode = IApplicationThread.DEBUG_OFF;
4912            if (mDebugApp != null && mDebugApp.equals(processName)) {
4913                testMode = mWaitForDebugger
4914                    ? IApplicationThread.DEBUG_WAIT
4915                    : IApplicationThread.DEBUG_ON;
4916                app.debugging = true;
4917                if (mDebugTransient) {
4918                    mDebugApp = mOrigDebugApp;
4919                    mWaitForDebugger = mOrigWaitForDebugger;
4920                }
4921            }
4922            String profileFile = app.instrumentationProfileFile;
4923            ParcelFileDescriptor profileFd = null;
4924            boolean profileAutoStop = false;
4925            if (mProfileApp != null && mProfileApp.equals(processName)) {
4926                mProfileProc = app;
4927                profileFile = mProfileFile;
4928                profileFd = mProfileFd;
4929                profileAutoStop = mAutoStopProfiler;
4930            }
4931            boolean enableOpenGlTrace = false;
4932            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4933                enableOpenGlTrace = true;
4934                mOpenGlTraceApp = null;
4935            }
4936
4937            // If the app is being launched for restore or full backup, set it up specially
4938            boolean isRestrictedBackupMode = false;
4939            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4940                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4941                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4942                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4943            }
4944
4945            ensurePackageDexOpt(app.instrumentationInfo != null
4946                    ? app.instrumentationInfo.packageName
4947                    : app.info.packageName);
4948            if (app.instrumentationClass != null) {
4949                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4950            }
4951            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4952                    + processName + " with config " + mConfiguration);
4953            ApplicationInfo appInfo = app.instrumentationInfo != null
4954                    ? app.instrumentationInfo : app.info;
4955            app.compat = compatibilityInfoForPackageLocked(appInfo);
4956            if (profileFd != null) {
4957                profileFd = profileFd.dup();
4958            }
4959            thread.bindApplication(processName, appInfo, providers,
4960                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4961                    app.instrumentationArguments, app.instrumentationWatcher,
4962                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4963                    isRestrictedBackupMode || !normalMode, app.persistent,
4964                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4965                    mCoreSettingsObserver.getCoreSettingsLocked());
4966            updateLruProcessLocked(app, false, null);
4967            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4968        } catch (Exception e) {
4969            // todo: Yikes!  What should we do?  For now we will try to
4970            // start another process, but that could easily get us in
4971            // an infinite loop of restarting processes...
4972            Slog.w(TAG, "Exception thrown during bind!", e);
4973
4974            app.resetPackageList(mProcessStats);
4975            app.unlinkDeathRecipient();
4976            startProcessLocked(app, "bind fail", processName);
4977            return false;
4978        }
4979
4980        // Remove this record from the list of starting applications.
4981        mPersistentStartingProcesses.remove(app);
4982        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4983                "Attach application locked removing on hold: " + app);
4984        mProcessesOnHold.remove(app);
4985
4986        boolean badApp = false;
4987        boolean didSomething = false;
4988
4989        // See if the top visible activity is waiting to run in this process...
4990        if (normalMode) {
4991            try {
4992                if (mStackSupervisor.attachApplicationLocked(app)) {
4993                    didSomething = true;
4994                }
4995            } catch (Exception e) {
4996                badApp = true;
4997            }
4998        }
4999
5000        // Find any services that should be running in this process...
5001        if (!badApp) {
5002            try {
5003                didSomething |= mServices.attachApplicationLocked(app, processName);
5004            } catch (Exception e) {
5005                badApp = true;
5006            }
5007        }
5008
5009        // Check if a next-broadcast receiver is in this process...
5010        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5011            try {
5012                didSomething |= sendPendingBroadcastsLocked(app);
5013            } catch (Exception e) {
5014                // If the app died trying to launch the receiver we declare it 'bad'
5015                badApp = true;
5016            }
5017        }
5018
5019        // Check whether the next backup agent is in this process...
5020        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5021            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5022            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5023            try {
5024                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5025                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5026                        mBackupTarget.backupMode);
5027            } catch (Exception e) {
5028                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5029                e.printStackTrace();
5030            }
5031        }
5032
5033        if (badApp) {
5034            // todo: Also need to kill application to deal with all
5035            // kinds of exceptions.
5036            handleAppDiedLocked(app, false, true);
5037            return false;
5038        }
5039
5040        if (!didSomething) {
5041            updateOomAdjLocked();
5042        }
5043
5044        return true;
5045    }
5046
5047    @Override
5048    public final void attachApplication(IApplicationThread thread) {
5049        synchronized (this) {
5050            int callingPid = Binder.getCallingPid();
5051            final long origId = Binder.clearCallingIdentity();
5052            attachApplicationLocked(thread, callingPid);
5053            Binder.restoreCallingIdentity(origId);
5054        }
5055    }
5056
5057    @Override
5058    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5059        final long origId = Binder.clearCallingIdentity();
5060        synchronized (this) {
5061            ActivityStack stack = ActivityRecord.getStackLocked(token);
5062            if (stack != null) {
5063                ActivityRecord r =
5064                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5065                if (stopProfiling) {
5066                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5067                        try {
5068                            mProfileFd.close();
5069                        } catch (IOException e) {
5070                        }
5071                        clearProfilerLocked();
5072                    }
5073                }
5074            }
5075        }
5076        Binder.restoreCallingIdentity(origId);
5077    }
5078
5079    void enableScreenAfterBoot() {
5080        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5081                SystemClock.uptimeMillis());
5082        mWindowManager.enableScreenAfterBoot();
5083
5084        synchronized (this) {
5085            updateEventDispatchingLocked();
5086        }
5087    }
5088
5089    @Override
5090    public void showBootMessage(final CharSequence msg, final boolean always) {
5091        enforceNotIsolatedCaller("showBootMessage");
5092        mWindowManager.showBootMessage(msg, always);
5093    }
5094
5095    @Override
5096    public void dismissKeyguardOnNextActivity() {
5097        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5098        final long token = Binder.clearCallingIdentity();
5099        try {
5100            synchronized (this) {
5101                if (DEBUG_LOCKSCREEN) logLockScreen("");
5102                if (mLockScreenShown) {
5103                    mLockScreenShown = false;
5104                    comeOutOfSleepIfNeededLocked();
5105                }
5106                mStackSupervisor.setDismissKeyguard(true);
5107            }
5108        } finally {
5109            Binder.restoreCallingIdentity(token);
5110        }
5111    }
5112
5113    final void finishBooting() {
5114        IntentFilter pkgFilter = new IntentFilter();
5115        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5116        pkgFilter.addDataScheme("package");
5117        mContext.registerReceiver(new BroadcastReceiver() {
5118            @Override
5119            public void onReceive(Context context, Intent intent) {
5120                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5121                if (pkgs != null) {
5122                    for (String pkg : pkgs) {
5123                        synchronized (ActivityManagerService.this) {
5124                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5125                                    "finished booting")) {
5126                                setResultCode(Activity.RESULT_OK);
5127                                return;
5128                            }
5129                        }
5130                    }
5131                }
5132            }
5133        }, pkgFilter);
5134
5135        synchronized (this) {
5136            // Ensure that any processes we had put on hold are now started
5137            // up.
5138            final int NP = mProcessesOnHold.size();
5139            if (NP > 0) {
5140                ArrayList<ProcessRecord> procs =
5141                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5142                for (int ip=0; ip<NP; ip++) {
5143                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5144                            + procs.get(ip));
5145                    startProcessLocked(procs.get(ip), "on-hold", null);
5146                }
5147            }
5148
5149            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
5150                // Start looking for apps that are abusing wake locks.
5151                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5152                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5153                // Tell anyone interested that we are done booting!
5154                SystemProperties.set("sys.boot_completed", "1");
5155                SystemProperties.set("dev.bootcomplete", "1");
5156                for (int i=0; i<mStartedUsers.size(); i++) {
5157                    UserStartedState uss = mStartedUsers.valueAt(i);
5158                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5159                        uss.mState = UserStartedState.STATE_RUNNING;
5160                        final int userId = mStartedUsers.keyAt(i);
5161                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5162                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5163                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5164                        broadcastIntentLocked(null, null, intent, null,
5165                                new IIntentReceiver.Stub() {
5166                                    @Override
5167                                    public void performReceive(Intent intent, int resultCode,
5168                                            String data, Bundle extras, boolean ordered,
5169                                            boolean sticky, int sendingUser) {
5170                                        synchronized (ActivityManagerService.this) {
5171                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5172                                                    true, false);
5173                                        }
5174                                    }
5175                                },
5176                                0, null, null,
5177                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5178                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5179                                userId);
5180                    }
5181                }
5182            }
5183        }
5184    }
5185
5186    final void ensureBootCompleted() {
5187        boolean booting;
5188        boolean enableScreen;
5189        synchronized (this) {
5190            booting = mBooting;
5191            mBooting = false;
5192            enableScreen = !mBooted;
5193            mBooted = true;
5194        }
5195
5196        if (booting) {
5197            finishBooting();
5198        }
5199
5200        if (enableScreen) {
5201            enableScreenAfterBoot();
5202        }
5203    }
5204
5205    @Override
5206    public final void activityResumed(IBinder token) {
5207        final long origId = Binder.clearCallingIdentity();
5208        synchronized(this) {
5209            ActivityStack stack = ActivityRecord.getStackLocked(token);
5210            if (stack != null) {
5211                ActivityRecord.activityResumedLocked(token);
5212            }
5213        }
5214        Binder.restoreCallingIdentity(origId);
5215    }
5216
5217    @Override
5218    public final void activityPaused(IBinder token) {
5219        final long origId = Binder.clearCallingIdentity();
5220        synchronized(this) {
5221            ActivityStack stack = ActivityRecord.getStackLocked(token);
5222            if (stack != null) {
5223                stack.activityPausedLocked(token, false);
5224            }
5225        }
5226        Binder.restoreCallingIdentity(origId);
5227    }
5228
5229    @Override
5230    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5231            CharSequence description) {
5232        if (localLOGV) Slog.v(
5233            TAG, "Activity stopped: token=" + token);
5234
5235        // Refuse possible leaked file descriptors
5236        if (icicle != null && icicle.hasFileDescriptors()) {
5237            throw new IllegalArgumentException("File descriptors passed in Bundle");
5238        }
5239
5240        ActivityRecord r = null;
5241
5242        final long origId = Binder.clearCallingIdentity();
5243
5244        synchronized (this) {
5245            r = ActivityRecord.isInStackLocked(token);
5246            if (r != null) {
5247                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5248            }
5249        }
5250
5251        if (r != null) {
5252            sendPendingThumbnail(r, null, null, null, false);
5253        }
5254
5255        trimApplications();
5256
5257        Binder.restoreCallingIdentity(origId);
5258    }
5259
5260    @Override
5261    public final void activityDestroyed(IBinder token) {
5262        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5263        synchronized (this) {
5264            ActivityStack stack = ActivityRecord.getStackLocked(token);
5265            if (stack != null) {
5266                stack.activityDestroyedLocked(token);
5267            }
5268        }
5269    }
5270
5271    @Override
5272    public String getCallingPackage(IBinder token) {
5273        synchronized (this) {
5274            ActivityRecord r = getCallingRecordLocked(token);
5275            return r != null ? r.info.packageName : null;
5276        }
5277    }
5278
5279    @Override
5280    public ComponentName getCallingActivity(IBinder token) {
5281        synchronized (this) {
5282            ActivityRecord r = getCallingRecordLocked(token);
5283            return r != null ? r.intent.getComponent() : null;
5284        }
5285    }
5286
5287    private ActivityRecord getCallingRecordLocked(IBinder token) {
5288        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5289        if (r == null) {
5290            return null;
5291        }
5292        return r.resultTo;
5293    }
5294
5295    @Override
5296    public ComponentName getActivityClassForToken(IBinder token) {
5297        synchronized(this) {
5298            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5299            if (r == null) {
5300                return null;
5301            }
5302            return r.intent.getComponent();
5303        }
5304    }
5305
5306    @Override
5307    public String getPackageForToken(IBinder token) {
5308        synchronized(this) {
5309            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5310            if (r == null) {
5311                return null;
5312            }
5313            return r.packageName;
5314        }
5315    }
5316
5317    @Override
5318    public IIntentSender getIntentSender(int type,
5319            String packageName, IBinder token, String resultWho,
5320            int requestCode, Intent[] intents, String[] resolvedTypes,
5321            int flags, Bundle options, int userId) {
5322        enforceNotIsolatedCaller("getIntentSender");
5323        // Refuse possible leaked file descriptors
5324        if (intents != null) {
5325            if (intents.length < 1) {
5326                throw new IllegalArgumentException("Intents array length must be >= 1");
5327            }
5328            for (int i=0; i<intents.length; i++) {
5329                Intent intent = intents[i];
5330                if (intent != null) {
5331                    if (intent.hasFileDescriptors()) {
5332                        throw new IllegalArgumentException("File descriptors passed in Intent");
5333                    }
5334                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5335                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5336                        throw new IllegalArgumentException(
5337                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5338                    }
5339                    intents[i] = new Intent(intent);
5340                }
5341            }
5342            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5343                throw new IllegalArgumentException(
5344                        "Intent array length does not match resolvedTypes length");
5345            }
5346        }
5347        if (options != null) {
5348            if (options.hasFileDescriptors()) {
5349                throw new IllegalArgumentException("File descriptors passed in options");
5350            }
5351        }
5352
5353        synchronized(this) {
5354            int callingUid = Binder.getCallingUid();
5355            int origUserId = userId;
5356            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5357                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5358                    "getIntentSender", null);
5359            if (origUserId == UserHandle.USER_CURRENT) {
5360                // We don't want to evaluate this until the pending intent is
5361                // actually executed.  However, we do want to always do the
5362                // security checking for it above.
5363                userId = UserHandle.USER_CURRENT;
5364            }
5365            try {
5366                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5367                    int uid = AppGlobals.getPackageManager()
5368                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5369                    if (!UserHandle.isSameApp(callingUid, uid)) {
5370                        String msg = "Permission Denial: getIntentSender() from pid="
5371                            + Binder.getCallingPid()
5372                            + ", uid=" + Binder.getCallingUid()
5373                            + ", (need uid=" + uid + ")"
5374                            + " is not allowed to send as package " + packageName;
5375                        Slog.w(TAG, msg);
5376                        throw new SecurityException(msg);
5377                    }
5378                }
5379
5380                return getIntentSenderLocked(type, packageName, callingUid, userId,
5381                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5382
5383            } catch (RemoteException e) {
5384                throw new SecurityException(e);
5385            }
5386        }
5387    }
5388
5389    IIntentSender getIntentSenderLocked(int type, String packageName,
5390            int callingUid, int userId, IBinder token, String resultWho,
5391            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5392            Bundle options) {
5393        if (DEBUG_MU)
5394            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5395        ActivityRecord activity = null;
5396        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5397            activity = ActivityRecord.isInStackLocked(token);
5398            if (activity == null) {
5399                return null;
5400            }
5401            if (activity.finishing) {
5402                return null;
5403            }
5404        }
5405
5406        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5407        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5408        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5409        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5410                |PendingIntent.FLAG_UPDATE_CURRENT);
5411
5412        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5413                type, packageName, activity, resultWho,
5414                requestCode, intents, resolvedTypes, flags, options, userId);
5415        WeakReference<PendingIntentRecord> ref;
5416        ref = mIntentSenderRecords.get(key);
5417        PendingIntentRecord rec = ref != null ? ref.get() : null;
5418        if (rec != null) {
5419            if (!cancelCurrent) {
5420                if (updateCurrent) {
5421                    if (rec.key.requestIntent != null) {
5422                        rec.key.requestIntent.replaceExtras(intents != null ?
5423                                intents[intents.length - 1] : null);
5424                    }
5425                    if (intents != null) {
5426                        intents[intents.length-1] = rec.key.requestIntent;
5427                        rec.key.allIntents = intents;
5428                        rec.key.allResolvedTypes = resolvedTypes;
5429                    } else {
5430                        rec.key.allIntents = null;
5431                        rec.key.allResolvedTypes = null;
5432                    }
5433                }
5434                return rec;
5435            }
5436            rec.canceled = true;
5437            mIntentSenderRecords.remove(key);
5438        }
5439        if (noCreate) {
5440            return rec;
5441        }
5442        rec = new PendingIntentRecord(this, key, callingUid);
5443        mIntentSenderRecords.put(key, rec.ref);
5444        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5445            if (activity.pendingResults == null) {
5446                activity.pendingResults
5447                        = new HashSet<WeakReference<PendingIntentRecord>>();
5448            }
5449            activity.pendingResults.add(rec.ref);
5450        }
5451        return rec;
5452    }
5453
5454    @Override
5455    public void cancelIntentSender(IIntentSender sender) {
5456        if (!(sender instanceof PendingIntentRecord)) {
5457            return;
5458        }
5459        synchronized(this) {
5460            PendingIntentRecord rec = (PendingIntentRecord)sender;
5461            try {
5462                int uid = AppGlobals.getPackageManager()
5463                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5464                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5465                    String msg = "Permission Denial: cancelIntentSender() from pid="
5466                        + Binder.getCallingPid()
5467                        + ", uid=" + Binder.getCallingUid()
5468                        + " is not allowed to cancel packges "
5469                        + rec.key.packageName;
5470                    Slog.w(TAG, msg);
5471                    throw new SecurityException(msg);
5472                }
5473            } catch (RemoteException e) {
5474                throw new SecurityException(e);
5475            }
5476            cancelIntentSenderLocked(rec, true);
5477        }
5478    }
5479
5480    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5481        rec.canceled = true;
5482        mIntentSenderRecords.remove(rec.key);
5483        if (cleanActivity && rec.key.activity != null) {
5484            rec.key.activity.pendingResults.remove(rec.ref);
5485        }
5486    }
5487
5488    @Override
5489    public String getPackageForIntentSender(IIntentSender pendingResult) {
5490        if (!(pendingResult instanceof PendingIntentRecord)) {
5491            return null;
5492        }
5493        try {
5494            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5495            return res.key.packageName;
5496        } catch (ClassCastException e) {
5497        }
5498        return null;
5499    }
5500
5501    @Override
5502    public int getUidForIntentSender(IIntentSender sender) {
5503        if (sender instanceof PendingIntentRecord) {
5504            try {
5505                PendingIntentRecord res = (PendingIntentRecord)sender;
5506                return res.uid;
5507            } catch (ClassCastException e) {
5508            }
5509        }
5510        return -1;
5511    }
5512
5513    @Override
5514    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5515        if (!(pendingResult instanceof PendingIntentRecord)) {
5516            return false;
5517        }
5518        try {
5519            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5520            if (res.key.allIntents == null) {
5521                return false;
5522            }
5523            for (int i=0; i<res.key.allIntents.length; i++) {
5524                Intent intent = res.key.allIntents[i];
5525                if (intent.getPackage() != null && intent.getComponent() != null) {
5526                    return false;
5527                }
5528            }
5529            return true;
5530        } catch (ClassCastException e) {
5531        }
5532        return false;
5533    }
5534
5535    @Override
5536    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5537        if (!(pendingResult instanceof PendingIntentRecord)) {
5538            return false;
5539        }
5540        try {
5541            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5542            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5543                return true;
5544            }
5545            return false;
5546        } catch (ClassCastException e) {
5547        }
5548        return false;
5549    }
5550
5551    @Override
5552    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5553        if (!(pendingResult instanceof PendingIntentRecord)) {
5554            return null;
5555        }
5556        try {
5557            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5558            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5559        } catch (ClassCastException e) {
5560        }
5561        return null;
5562    }
5563
5564    @Override
5565    public void setProcessLimit(int max) {
5566        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5567                "setProcessLimit()");
5568        synchronized (this) {
5569            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5570            mProcessLimitOverride = max;
5571        }
5572        trimApplications();
5573    }
5574
5575    @Override
5576    public int getProcessLimit() {
5577        synchronized (this) {
5578            return mProcessLimitOverride;
5579        }
5580    }
5581
5582    void foregroundTokenDied(ForegroundToken token) {
5583        synchronized (ActivityManagerService.this) {
5584            synchronized (mPidsSelfLocked) {
5585                ForegroundToken cur
5586                    = mForegroundProcesses.get(token.pid);
5587                if (cur != token) {
5588                    return;
5589                }
5590                mForegroundProcesses.remove(token.pid);
5591                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5592                if (pr == null) {
5593                    return;
5594                }
5595                pr.forcingToForeground = null;
5596                pr.foregroundServices = false;
5597            }
5598            updateOomAdjLocked();
5599        }
5600    }
5601
5602    @Override
5603    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5604        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5605                "setProcessForeground()");
5606        synchronized(this) {
5607            boolean changed = false;
5608
5609            synchronized (mPidsSelfLocked) {
5610                ProcessRecord pr = mPidsSelfLocked.get(pid);
5611                if (pr == null && isForeground) {
5612                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5613                    return;
5614                }
5615                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5616                if (oldToken != null) {
5617                    oldToken.token.unlinkToDeath(oldToken, 0);
5618                    mForegroundProcesses.remove(pid);
5619                    if (pr != null) {
5620                        pr.forcingToForeground = null;
5621                    }
5622                    changed = true;
5623                }
5624                if (isForeground && token != null) {
5625                    ForegroundToken newToken = new ForegroundToken() {
5626                        @Override
5627                        public void binderDied() {
5628                            foregroundTokenDied(this);
5629                        }
5630                    };
5631                    newToken.pid = pid;
5632                    newToken.token = token;
5633                    try {
5634                        token.linkToDeath(newToken, 0);
5635                        mForegroundProcesses.put(pid, newToken);
5636                        pr.forcingToForeground = token;
5637                        changed = true;
5638                    } catch (RemoteException e) {
5639                        // If the process died while doing this, we will later
5640                        // do the cleanup with the process death link.
5641                    }
5642                }
5643            }
5644
5645            if (changed) {
5646                updateOomAdjLocked();
5647            }
5648        }
5649    }
5650
5651    // =========================================================
5652    // PERMISSIONS
5653    // =========================================================
5654
5655    static class PermissionController extends IPermissionController.Stub {
5656        ActivityManagerService mActivityManagerService;
5657        PermissionController(ActivityManagerService activityManagerService) {
5658            mActivityManagerService = activityManagerService;
5659        }
5660
5661        @Override
5662        public boolean checkPermission(String permission, int pid, int uid) {
5663            return mActivityManagerService.checkPermission(permission, pid,
5664                    uid) == PackageManager.PERMISSION_GRANTED;
5665        }
5666    }
5667
5668    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5669        @Override
5670        public int checkComponentPermission(String permission, int pid, int uid,
5671                int owningUid, boolean exported) {
5672            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5673                    owningUid, exported);
5674        }
5675
5676        @Override
5677        public Object getAMSLock() {
5678            return ActivityManagerService.this;
5679        }
5680    }
5681
5682    /**
5683     * This can be called with or without the global lock held.
5684     */
5685    int checkComponentPermission(String permission, int pid, int uid,
5686            int owningUid, boolean exported) {
5687        // We might be performing an operation on behalf of an indirect binder
5688        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5689        // client identity accordingly before proceeding.
5690        Identity tlsIdentity = sCallerIdentity.get();
5691        if (tlsIdentity != null) {
5692            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5693                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5694            uid = tlsIdentity.uid;
5695            pid = tlsIdentity.pid;
5696        }
5697
5698        if (pid == MY_PID) {
5699            return PackageManager.PERMISSION_GRANTED;
5700        }
5701
5702        return ActivityManager.checkComponentPermission(permission, uid,
5703                owningUid, exported);
5704    }
5705
5706    /**
5707     * As the only public entry point for permissions checking, this method
5708     * can enforce the semantic that requesting a check on a null global
5709     * permission is automatically denied.  (Internally a null permission
5710     * string is used when calling {@link #checkComponentPermission} in cases
5711     * when only uid-based security is needed.)
5712     *
5713     * This can be called with or without the global lock held.
5714     */
5715    @Override
5716    public int checkPermission(String permission, int pid, int uid) {
5717        if (permission == null) {
5718            return PackageManager.PERMISSION_DENIED;
5719        }
5720        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5721    }
5722
5723    /**
5724     * Binder IPC calls go through the public entry point.
5725     * This can be called with or without the global lock held.
5726     */
5727    int checkCallingPermission(String permission) {
5728        return checkPermission(permission,
5729                Binder.getCallingPid(),
5730                UserHandle.getAppId(Binder.getCallingUid()));
5731    }
5732
5733    /**
5734     * This can be called with or without the global lock held.
5735     */
5736    void enforceCallingPermission(String permission, String func) {
5737        if (checkCallingPermission(permission)
5738                == PackageManager.PERMISSION_GRANTED) {
5739            return;
5740        }
5741
5742        String msg = "Permission Denial: " + func + " from pid="
5743                + Binder.getCallingPid()
5744                + ", uid=" + Binder.getCallingUid()
5745                + " requires " + permission;
5746        Slog.w(TAG, msg);
5747        throw new SecurityException(msg);
5748    }
5749
5750    /**
5751     * Determine if UID is holding permissions required to access {@link Uri} in
5752     * the given {@link ProviderInfo}. Final permission checking is always done
5753     * in {@link ContentProvider}.
5754     */
5755    private final boolean checkHoldingPermissionsLocked(
5756            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5757        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5758                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5759
5760        if (pi.applicationInfo.uid == uid) {
5761            return true;
5762        } else if (!pi.exported) {
5763            return false;
5764        }
5765
5766        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5767        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5768        try {
5769            // check if target holds top-level <provider> permissions
5770            if (!readMet && pi.readPermission != null
5771                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5772                readMet = true;
5773            }
5774            if (!writeMet && pi.writePermission != null
5775                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5776                writeMet = true;
5777            }
5778
5779            // track if unprotected read/write is allowed; any denied
5780            // <path-permission> below removes this ability
5781            boolean allowDefaultRead = pi.readPermission == null;
5782            boolean allowDefaultWrite = pi.writePermission == null;
5783
5784            // check if target holds any <path-permission> that match uri
5785            final PathPermission[] pps = pi.pathPermissions;
5786            if (pps != null) {
5787                final String path = uri.getPath();
5788                int i = pps.length;
5789                while (i > 0 && (!readMet || !writeMet)) {
5790                    i--;
5791                    PathPermission pp = pps[i];
5792                    if (pp.match(path)) {
5793                        if (!readMet) {
5794                            final String pprperm = pp.getReadPermission();
5795                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5796                                    + pprperm + " for " + pp.getPath()
5797                                    + ": match=" + pp.match(path)
5798                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5799                            if (pprperm != null) {
5800                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5801                                    readMet = true;
5802                                } else {
5803                                    allowDefaultRead = false;
5804                                }
5805                            }
5806                        }
5807                        if (!writeMet) {
5808                            final String ppwperm = pp.getWritePermission();
5809                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5810                                    + ppwperm + " for " + pp.getPath()
5811                                    + ": match=" + pp.match(path)
5812                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5813                            if (ppwperm != null) {
5814                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5815                                    writeMet = true;
5816                                } else {
5817                                    allowDefaultWrite = false;
5818                                }
5819                            }
5820                        }
5821                    }
5822                }
5823            }
5824
5825            // grant unprotected <provider> read/write, if not blocked by
5826            // <path-permission> above
5827            if (allowDefaultRead) readMet = true;
5828            if (allowDefaultWrite) writeMet = true;
5829
5830        } catch (RemoteException e) {
5831            return false;
5832        }
5833
5834        return readMet && writeMet;
5835    }
5836
5837    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5838        ProviderInfo pi = null;
5839        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5840        if (cpr != null) {
5841            pi = cpr.info;
5842        } else {
5843            try {
5844                pi = AppGlobals.getPackageManager().resolveContentProvider(
5845                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5846            } catch (RemoteException ex) {
5847            }
5848        }
5849        return pi;
5850    }
5851
5852    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5853        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5854        if (targetUris != null) {
5855            return targetUris.get(uri);
5856        } else {
5857            return null;
5858        }
5859    }
5860
5861    private UriPermission findOrCreateUriPermissionLocked(
5862            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5863        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5864        if (targetUris == null) {
5865            targetUris = Maps.newArrayMap();
5866            mGrantedUriPermissions.put(targetUid, targetUris);
5867        }
5868
5869        UriPermission perm = targetUris.get(uri);
5870        if (perm == null) {
5871            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5872            targetUris.put(uri, perm);
5873        }
5874
5875        return perm;
5876    }
5877
5878    private final boolean checkUriPermissionLocked(
5879            Uri uri, int uid, int modeFlags, int minStrength) {
5880        // Root gets to do everything.
5881        if (uid == 0) {
5882            return true;
5883        }
5884        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5885        if (perms == null) return false;
5886        UriPermission perm = perms.get(uri);
5887        if (perm == null) return false;
5888        return perm.getStrength(modeFlags) >= minStrength;
5889    }
5890
5891    @Override
5892    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5893        enforceNotIsolatedCaller("checkUriPermission");
5894
5895        // Another redirected-binder-call permissions check as in
5896        // {@link checkComponentPermission}.
5897        Identity tlsIdentity = sCallerIdentity.get();
5898        if (tlsIdentity != null) {
5899            uid = tlsIdentity.uid;
5900            pid = tlsIdentity.pid;
5901        }
5902
5903        // Our own process gets to do everything.
5904        if (pid == MY_PID) {
5905            return PackageManager.PERMISSION_GRANTED;
5906        }
5907        synchronized(this) {
5908            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5909                    ? PackageManager.PERMISSION_GRANTED
5910                    : PackageManager.PERMISSION_DENIED;
5911        }
5912    }
5913
5914    /**
5915     * Check if the targetPkg can be granted permission to access uri by
5916     * the callingUid using the given modeFlags.  Throws a security exception
5917     * if callingUid is not allowed to do this.  Returns the uid of the target
5918     * if the URI permission grant should be performed; returns -1 if it is not
5919     * needed (for example targetPkg already has permission to access the URI).
5920     * If you already know the uid of the target, you can supply it in
5921     * lastTargetUid else set that to -1.
5922     */
5923    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5924            Uri uri, int modeFlags, int lastTargetUid) {
5925        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5926        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5927                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5928        if (modeFlags == 0) {
5929            return -1;
5930        }
5931
5932        if (targetPkg != null) {
5933            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5934                    "Checking grant " + targetPkg + " permission to " + uri);
5935        }
5936
5937        final IPackageManager pm = AppGlobals.getPackageManager();
5938
5939        // If this is not a content: uri, we can't do anything with it.
5940        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5941            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5942                    "Can't grant URI permission for non-content URI: " + uri);
5943            return -1;
5944        }
5945
5946        final String authority = uri.getAuthority();
5947        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5948        if (pi == null) {
5949            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5950            return -1;
5951        }
5952
5953        int targetUid = lastTargetUid;
5954        if (targetUid < 0 && targetPkg != null) {
5955            try {
5956                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5957                if (targetUid < 0) {
5958                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5959                            "Can't grant URI permission no uid for: " + targetPkg);
5960                    return -1;
5961                }
5962            } catch (RemoteException ex) {
5963                return -1;
5964            }
5965        }
5966
5967        if (targetUid >= 0) {
5968            // First...  does the target actually need this permission?
5969            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5970                // No need to grant the target this permission.
5971                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5972                        "Target " + targetPkg + " already has full permission to " + uri);
5973                return -1;
5974            }
5975        } else {
5976            // First...  there is no target package, so can anyone access it?
5977            boolean allowed = pi.exported;
5978            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5979                if (pi.readPermission != null) {
5980                    allowed = false;
5981                }
5982            }
5983            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5984                if (pi.writePermission != null) {
5985                    allowed = false;
5986                }
5987            }
5988            if (allowed) {
5989                return -1;
5990            }
5991        }
5992
5993        // Second...  is the provider allowing granting of URI permissions?
5994        if (!pi.grantUriPermissions) {
5995            throw new SecurityException("Provider " + pi.packageName
5996                    + "/" + pi.name
5997                    + " does not allow granting of Uri permissions (uri "
5998                    + uri + ")");
5999        }
6000        if (pi.uriPermissionPatterns != null) {
6001            final int N = pi.uriPermissionPatterns.length;
6002            boolean allowed = false;
6003            for (int i=0; i<N; i++) {
6004                if (pi.uriPermissionPatterns[i] != null
6005                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6006                    allowed = true;
6007                    break;
6008                }
6009            }
6010            if (!allowed) {
6011                throw new SecurityException("Provider " + pi.packageName
6012                        + "/" + pi.name
6013                        + " does not allow granting of permission to path of Uri "
6014                        + uri);
6015            }
6016        }
6017
6018        // Third...  does the caller itself have permission to access
6019        // this uri?
6020        if (callingUid != Process.myUid()) {
6021            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6022                // Require they hold a strong enough Uri permission
6023                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6024                        : UriPermission.STRENGTH_OWNED;
6025                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6026                    throw new SecurityException("Uid " + callingUid
6027                            + " does not have permission to uri " + uri);
6028                }
6029            }
6030        }
6031
6032        return targetUid;
6033    }
6034
6035    @Override
6036    public int checkGrantUriPermission(int callingUid, String targetPkg,
6037            Uri uri, int modeFlags) {
6038        enforceNotIsolatedCaller("checkGrantUriPermission");
6039        synchronized(this) {
6040            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6041        }
6042    }
6043
6044    void grantUriPermissionUncheckedLocked(
6045            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6046        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6047        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6048                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6049        if (modeFlags == 0) {
6050            return;
6051        }
6052
6053        // So here we are: the caller has the assumed permission
6054        // to the uri, and the target doesn't.  Let's now give this to
6055        // the target.
6056
6057        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6058                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6059
6060        final String authority = uri.getAuthority();
6061        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6062        if (pi == null) {
6063            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6064            return;
6065        }
6066
6067        final UriPermission perm = findOrCreateUriPermissionLocked(
6068                pi.packageName, targetPkg, targetUid, uri);
6069        perm.grantModes(modeFlags, persistable, owner);
6070    }
6071
6072    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6073            int modeFlags, UriPermissionOwner owner) {
6074        if (targetPkg == null) {
6075            throw new NullPointerException("targetPkg");
6076        }
6077
6078        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6079        if (targetUid < 0) {
6080            return;
6081        }
6082
6083        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6084    }
6085
6086    static class NeededUriGrants extends ArrayList<Uri> {
6087        final String targetPkg;
6088        final int targetUid;
6089        final int flags;
6090
6091        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6092            this.targetPkg = targetPkg;
6093            this.targetUid = targetUid;
6094            this.flags = flags;
6095        }
6096    }
6097
6098    /**
6099     * Like checkGrantUriPermissionLocked, but takes an Intent.
6100     */
6101    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6102            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6103        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6104                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6105                + " clip=" + (intent != null ? intent.getClipData() : null)
6106                + " from " + intent + "; flags=0x"
6107                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6108
6109        if (targetPkg == null) {
6110            throw new NullPointerException("targetPkg");
6111        }
6112
6113        if (intent == null) {
6114            return null;
6115        }
6116        Uri data = intent.getData();
6117        ClipData clip = intent.getClipData();
6118        if (data == null && clip == null) {
6119            return null;
6120        }
6121
6122        if (data != null) {
6123            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6124                mode, needed != null ? needed.targetUid : -1);
6125            if (targetUid > 0) {
6126                if (needed == null) {
6127                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6128                }
6129                needed.add(data);
6130            }
6131        }
6132        if (clip != null) {
6133            for (int i=0; i<clip.getItemCount(); i++) {
6134                Uri uri = clip.getItemAt(i).getUri();
6135                if (uri != null) {
6136                    int targetUid = -1;
6137                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6138                            mode, needed != null ? needed.targetUid : -1);
6139                    if (targetUid > 0) {
6140                        if (needed == null) {
6141                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6142                        }
6143                        needed.add(uri);
6144                    }
6145                } else {
6146                    Intent clipIntent = clip.getItemAt(i).getIntent();
6147                    if (clipIntent != null) {
6148                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6149                                callingUid, targetPkg, clipIntent, mode, needed);
6150                        if (newNeeded != null) {
6151                            needed = newNeeded;
6152                        }
6153                    }
6154                }
6155            }
6156        }
6157
6158        return needed;
6159    }
6160
6161    /**
6162     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6163     */
6164    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6165            UriPermissionOwner owner) {
6166        if (needed != null) {
6167            for (int i=0; i<needed.size(); i++) {
6168                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6169                        needed.get(i), needed.flags, owner);
6170            }
6171        }
6172    }
6173
6174    void grantUriPermissionFromIntentLocked(int callingUid,
6175            String targetPkg, Intent intent, UriPermissionOwner owner) {
6176        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6177                intent, intent != null ? intent.getFlags() : 0, null);
6178        if (needed == null) {
6179            return;
6180        }
6181
6182        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6183    }
6184
6185    @Override
6186    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6187            Uri uri, int modeFlags) {
6188        enforceNotIsolatedCaller("grantUriPermission");
6189        synchronized(this) {
6190            final ProcessRecord r = getRecordForAppLocked(caller);
6191            if (r == null) {
6192                throw new SecurityException("Unable to find app for caller "
6193                        + caller
6194                        + " when granting permission to uri " + uri);
6195            }
6196            if (targetPkg == null) {
6197                throw new IllegalArgumentException("null target");
6198            }
6199            if (uri == null) {
6200                throw new IllegalArgumentException("null uri");
6201            }
6202
6203            // Persistable only supported through Intents
6204            Preconditions.checkFlagsArgument(modeFlags,
6205                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6206
6207            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6208                    null);
6209        }
6210    }
6211
6212    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6213        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6214                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6215            ArrayMap<Uri, UriPermission> perms
6216                    = mGrantedUriPermissions.get(perm.targetUid);
6217            if (perms != null) {
6218                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6219                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6220                perms.remove(perm.uri);
6221                if (perms.size() == 0) {
6222                    mGrantedUriPermissions.remove(perm.targetUid);
6223                }
6224            }
6225        }
6226    }
6227
6228    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6229        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6230
6231        final IPackageManager pm = AppGlobals.getPackageManager();
6232        final String authority = uri.getAuthority();
6233        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6234        if (pi == null) {
6235            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6236            return;
6237        }
6238
6239        // Does the caller have this permission on the URI?
6240        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6241            // Right now, if you are not the original owner of the permission,
6242            // you are not allowed to revoke it.
6243            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6244                throw new SecurityException("Uid " + callingUid
6245                        + " does not have permission to uri " + uri);
6246            //}
6247        }
6248
6249        boolean persistChanged = false;
6250
6251        // Go through all of the permissions and remove any that match.
6252        final List<String> SEGMENTS = uri.getPathSegments();
6253        if (SEGMENTS != null) {
6254            final int NS = SEGMENTS.size();
6255            int N = mGrantedUriPermissions.size();
6256            for (int i=0; i<N; i++) {
6257                ArrayMap<Uri, UriPermission> perms
6258                        = mGrantedUriPermissions.valueAt(i);
6259                Iterator<UriPermission> it = perms.values().iterator();
6260            toploop:
6261                while (it.hasNext()) {
6262                    UriPermission perm = it.next();
6263                    Uri targetUri = perm.uri;
6264                    if (!authority.equals(targetUri.getAuthority())) {
6265                        continue;
6266                    }
6267                    List<String> targetSegments = targetUri.getPathSegments();
6268                    if (targetSegments == null) {
6269                        continue;
6270                    }
6271                    if (targetSegments.size() < NS) {
6272                        continue;
6273                    }
6274                    for (int j=0; j<NS; j++) {
6275                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6276                            continue toploop;
6277                        }
6278                    }
6279                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6280                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6281                    persistChanged |= perm.clearModes(modeFlags, true);
6282                    if (perm.modeFlags == 0) {
6283                        it.remove();
6284                    }
6285                }
6286                if (perms.size() == 0) {
6287                    mGrantedUriPermissions.remove(
6288                            mGrantedUriPermissions.keyAt(i));
6289                    N--;
6290                    i--;
6291                }
6292            }
6293        }
6294
6295        if (persistChanged) {
6296            schedulePersistUriGrants();
6297        }
6298    }
6299
6300    @Override
6301    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6302            int modeFlags) {
6303        enforceNotIsolatedCaller("revokeUriPermission");
6304        synchronized(this) {
6305            final ProcessRecord r = getRecordForAppLocked(caller);
6306            if (r == null) {
6307                throw new SecurityException("Unable to find app for caller "
6308                        + caller
6309                        + " when revoking permission to uri " + uri);
6310            }
6311            if (uri == null) {
6312                Slog.w(TAG, "revokeUriPermission: null uri");
6313                return;
6314            }
6315
6316            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6317                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6318            if (modeFlags == 0) {
6319                return;
6320            }
6321
6322            final IPackageManager pm = AppGlobals.getPackageManager();
6323            final String authority = uri.getAuthority();
6324            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6325            if (pi == null) {
6326                Slog.w(TAG, "No content provider found for permission revoke: "
6327                        + uri.toSafeString());
6328                return;
6329            }
6330
6331            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6332        }
6333    }
6334
6335    /**
6336     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6337     * given package.
6338     *
6339     * @param packageName Package name to match, or {@code null} to apply to all
6340     *            packages.
6341     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6342     *            to all users.
6343     * @param persistable If persistable grants should be removed.
6344     */
6345    private void removeUriPermissionsForPackageLocked(
6346            String packageName, int userHandle, boolean persistable) {
6347        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6348            throw new IllegalArgumentException("Must narrow by either package or user");
6349        }
6350
6351        boolean persistChanged = false;
6352
6353        final int size = mGrantedUriPermissions.size();
6354        for (int i = 0; i < size; i++) {
6355            // Only inspect grants matching user
6356            if (userHandle == UserHandle.USER_ALL
6357                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6358                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6359                        .values().iterator();
6360                while (it.hasNext()) {
6361                    final UriPermission perm = it.next();
6362
6363                    // Only inspect grants matching package
6364                    if (packageName == null || perm.sourcePkg.equals(packageName)
6365                            || perm.targetPkg.equals(packageName)) {
6366                        persistChanged |= perm.clearModes(~0, persistable);
6367
6368                        // Only remove when no modes remain; any persisted grants
6369                        // will keep this alive.
6370                        if (perm.modeFlags == 0) {
6371                            it.remove();
6372                        }
6373                    }
6374                }
6375            }
6376        }
6377
6378        if (persistChanged) {
6379            schedulePersistUriGrants();
6380        }
6381    }
6382
6383    @Override
6384    public IBinder newUriPermissionOwner(String name) {
6385        enforceNotIsolatedCaller("newUriPermissionOwner");
6386        synchronized(this) {
6387            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6388            return owner.getExternalTokenLocked();
6389        }
6390    }
6391
6392    @Override
6393    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6394            Uri uri, int modeFlags) {
6395        synchronized(this) {
6396            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6397            if (owner == null) {
6398                throw new IllegalArgumentException("Unknown owner: " + token);
6399            }
6400            if (fromUid != Binder.getCallingUid()) {
6401                if (Binder.getCallingUid() != Process.myUid()) {
6402                    // Only system code can grant URI permissions on behalf
6403                    // of other users.
6404                    throw new SecurityException("nice try");
6405                }
6406            }
6407            if (targetPkg == null) {
6408                throw new IllegalArgumentException("null target");
6409            }
6410            if (uri == null) {
6411                throw new IllegalArgumentException("null uri");
6412            }
6413
6414            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6415        }
6416    }
6417
6418    @Override
6419    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6420        synchronized(this) {
6421            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6422            if (owner == null) {
6423                throw new IllegalArgumentException("Unknown owner: " + token);
6424            }
6425
6426            if (uri == null) {
6427                owner.removeUriPermissionsLocked(mode);
6428            } else {
6429                owner.removeUriPermissionLocked(uri, mode);
6430            }
6431        }
6432    }
6433
6434    private void schedulePersistUriGrants() {
6435        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6436            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6437                    10 * DateUtils.SECOND_IN_MILLIS);
6438        }
6439    }
6440
6441    private void writeGrantedUriPermissions() {
6442        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6443
6444        // Snapshot permissions so we can persist without lock
6445        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6446        synchronized (this) {
6447            final int size = mGrantedUriPermissions.size();
6448            for (int i = 0 ; i < size; i++) {
6449                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6450                    if (perm.persistedModeFlags != 0) {
6451                        persist.add(perm.snapshot());
6452                    }
6453                }
6454            }
6455        }
6456
6457        FileOutputStream fos = null;
6458        try {
6459            fos = mGrantFile.startWrite();
6460
6461            XmlSerializer out = new FastXmlSerializer();
6462            out.setOutput(fos, "utf-8");
6463            out.startDocument(null, true);
6464            out.startTag(null, TAG_URI_GRANTS);
6465            for (UriPermission.Snapshot perm : persist) {
6466                out.startTag(null, TAG_URI_GRANT);
6467                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6468                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6469                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6470                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6471                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6472                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6473                out.endTag(null, TAG_URI_GRANT);
6474            }
6475            out.endTag(null, TAG_URI_GRANTS);
6476            out.endDocument();
6477
6478            mGrantFile.finishWrite(fos);
6479        } catch (IOException e) {
6480            if (fos != null) {
6481                mGrantFile.failWrite(fos);
6482            }
6483        }
6484    }
6485
6486    private void readGrantedUriPermissionsLocked() {
6487        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6488
6489        final long now = System.currentTimeMillis();
6490
6491        FileInputStream fis = null;
6492        try {
6493            fis = mGrantFile.openRead();
6494            final XmlPullParser in = Xml.newPullParser();
6495            in.setInput(fis, null);
6496
6497            int type;
6498            while ((type = in.next()) != END_DOCUMENT) {
6499                final String tag = in.getName();
6500                if (type == START_TAG) {
6501                    if (TAG_URI_GRANT.equals(tag)) {
6502                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6503                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6504                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6505                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6506                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6507                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6508
6509                        // Sanity check that provider still belongs to source package
6510                        final ProviderInfo pi = getProviderInfoLocked(
6511                                uri.getAuthority(), userHandle);
6512                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6513                            int targetUid = -1;
6514                            try {
6515                                targetUid = AppGlobals.getPackageManager()
6516                                        .getPackageUid(targetPkg, userHandle);
6517                            } catch (RemoteException e) {
6518                            }
6519                            if (targetUid != -1) {
6520                                final UriPermission perm = findOrCreateUriPermissionLocked(
6521                                        sourcePkg, targetPkg, targetUid, uri);
6522                                perm.initPersistedModes(modeFlags, createdTime);
6523                            }
6524                        } else {
6525                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6526                                    + " but instead found " + pi);
6527                        }
6528                    }
6529                }
6530            }
6531        } catch (FileNotFoundException e) {
6532            // Missing grants is okay
6533        } catch (IOException e) {
6534            Log.wtf(TAG, "Failed reading Uri grants", e);
6535        } catch (XmlPullParserException e) {
6536            Log.wtf(TAG, "Failed reading Uri grants", e);
6537        } finally {
6538            IoUtils.closeQuietly(fis);
6539        }
6540    }
6541
6542    @Override
6543    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6544        enforceNotIsolatedCaller("takePersistableUriPermission");
6545
6546        Preconditions.checkFlagsArgument(modeFlags,
6547                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6548
6549        synchronized (this) {
6550            final int callingUid = Binder.getCallingUid();
6551            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6552            if (perm == null) {
6553                throw new SecurityException("No permission grant found for UID " + callingUid
6554                        + " and Uri " + uri.toSafeString());
6555            }
6556
6557            boolean persistChanged = perm.takePersistableModes(modeFlags);
6558            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6559
6560            if (persistChanged) {
6561                schedulePersistUriGrants();
6562            }
6563        }
6564    }
6565
6566    @Override
6567    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6568        enforceNotIsolatedCaller("releasePersistableUriPermission");
6569
6570        Preconditions.checkFlagsArgument(modeFlags,
6571                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6572
6573        synchronized (this) {
6574            final int callingUid = Binder.getCallingUid();
6575
6576            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6577            if (perm == null) {
6578                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6579                        + uri.toSafeString());
6580                return;
6581            }
6582
6583            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6584            removeUriPermissionIfNeededLocked(perm);
6585            if (persistChanged) {
6586                schedulePersistUriGrants();
6587            }
6588        }
6589    }
6590
6591    /**
6592     * Prune any older {@link UriPermission} for the given UID until outstanding
6593     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6594     *
6595     * @return if any mutations occured that require persisting.
6596     */
6597    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6598        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6599        if (perms == null) return false;
6600        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6601
6602        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6603        for (UriPermission perm : perms.values()) {
6604            if (perm.persistedModeFlags != 0) {
6605                persisted.add(perm);
6606            }
6607        }
6608
6609        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6610        if (trimCount <= 0) return false;
6611
6612        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6613        for (int i = 0; i < trimCount; i++) {
6614            final UriPermission perm = persisted.get(i);
6615
6616            if (DEBUG_URI_PERMISSION) {
6617                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6618            }
6619
6620            perm.releasePersistableModes(~0);
6621            removeUriPermissionIfNeededLocked(perm);
6622        }
6623
6624        return true;
6625    }
6626
6627    @Override
6628    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6629            String packageName, boolean incoming) {
6630        enforceNotIsolatedCaller("getPersistedUriPermissions");
6631        Preconditions.checkNotNull(packageName, "packageName");
6632
6633        final int callingUid = Binder.getCallingUid();
6634        final IPackageManager pm = AppGlobals.getPackageManager();
6635        try {
6636            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6637            if (packageUid != callingUid) {
6638                throw new SecurityException(
6639                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6640            }
6641        } catch (RemoteException e) {
6642            throw new SecurityException("Failed to verify package name ownership");
6643        }
6644
6645        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6646        synchronized (this) {
6647            if (incoming) {
6648                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6649                if (perms == null) {
6650                    Slog.w(TAG, "No permission grants found for " + packageName);
6651                } else {
6652                    final int size = perms.size();
6653                    for (int i = 0; i < size; i++) {
6654                        final UriPermission perm = perms.valueAt(i);
6655                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6656                            result.add(perm.buildPersistedPublicApiObject());
6657                        }
6658                    }
6659                }
6660            } else {
6661                final int size = mGrantedUriPermissions.size();
6662                for (int i = 0; i < size; i++) {
6663                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6664                    final int permsSize = perms.size();
6665                    for (int j = 0; j < permsSize; j++) {
6666                        final UriPermission perm = perms.valueAt(j);
6667                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6668                            result.add(perm.buildPersistedPublicApiObject());
6669                        }
6670                    }
6671                }
6672            }
6673        }
6674        return new ParceledListSlice<android.content.UriPermission>(result);
6675    }
6676
6677    @Override
6678    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6679        synchronized (this) {
6680            ProcessRecord app =
6681                who != null ? getRecordForAppLocked(who) : null;
6682            if (app == null) return;
6683
6684            Message msg = Message.obtain();
6685            msg.what = WAIT_FOR_DEBUGGER_MSG;
6686            msg.obj = app;
6687            msg.arg1 = waiting ? 1 : 0;
6688            mHandler.sendMessage(msg);
6689        }
6690    }
6691
6692    @Override
6693    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6694        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6695        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6696        outInfo.availMem = Process.getFreeMemory();
6697        outInfo.totalMem = Process.getTotalMemory();
6698        outInfo.threshold = homeAppMem;
6699        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6700        outInfo.hiddenAppThreshold = cachedAppMem;
6701        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6702                ProcessList.SERVICE_ADJ);
6703        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6704                ProcessList.VISIBLE_APP_ADJ);
6705        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6706                ProcessList.FOREGROUND_APP_ADJ);
6707    }
6708
6709    // =========================================================
6710    // TASK MANAGEMENT
6711    // =========================================================
6712
6713    @Override
6714    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6715                         IThumbnailReceiver receiver) {
6716        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6717
6718        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6719        ActivityRecord topRecord = null;
6720
6721        synchronized(this) {
6722            if (localLOGV) Slog.v(
6723                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6724                + ", receiver=" + receiver);
6725
6726            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6727                    != PackageManager.PERMISSION_GRANTED) {
6728                if (receiver != null) {
6729                    // If the caller wants to wait for pending thumbnails,
6730                    // it ain't gonna get them.
6731                    try {
6732                        receiver.finished();
6733                    } catch (RemoteException ex) {
6734                    }
6735                }
6736                String msg = "Permission Denial: getTasks() from pid="
6737                        + Binder.getCallingPid()
6738                        + ", uid=" + Binder.getCallingUid()
6739                        + " requires " + android.Manifest.permission.GET_TASKS;
6740                Slog.w(TAG, msg);
6741                throw new SecurityException(msg);
6742            }
6743
6744            // TODO: Improve with MRU list from all ActivityStacks.
6745            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6746
6747            if (!pending.pendingRecords.isEmpty()) {
6748                mPendingThumbnails.add(pending);
6749            }
6750        }
6751
6752        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6753
6754        if (topRecord != null) {
6755            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6756            try {
6757                IApplicationThread topThumbnail = topRecord.app.thread;
6758                topThumbnail.requestThumbnail(topRecord.appToken);
6759            } catch (Exception e) {
6760                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6761                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6762            }
6763        }
6764
6765        if (pending == null && receiver != null) {
6766            // In this case all thumbnails were available and the client
6767            // is being asked to be told when the remaining ones come in...
6768            // which is unusually, since the top-most currently running
6769            // activity should never have a canned thumbnail!  Oh well.
6770            try {
6771                receiver.finished();
6772            } catch (RemoteException ex) {
6773            }
6774        }
6775
6776        return list;
6777    }
6778
6779    TaskRecord getMostRecentTask() {
6780        return mRecentTasks.get(0);
6781    }
6782
6783    @Override
6784    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6785            int flags, int userId) {
6786        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6787                false, true, "getRecentTasks", null);
6788
6789        synchronized (this) {
6790            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6791                    "getRecentTasks()");
6792            final boolean detailed = checkCallingPermission(
6793                    android.Manifest.permission.GET_DETAILED_TASKS)
6794                    == PackageManager.PERMISSION_GRANTED;
6795
6796            IPackageManager pm = AppGlobals.getPackageManager();
6797
6798            final int N = mRecentTasks.size();
6799            ArrayList<ActivityManager.RecentTaskInfo> res
6800                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6801                            maxNum < N ? maxNum : N);
6802            for (int i=0; i<N && maxNum > 0; i++) {
6803                TaskRecord tr = mRecentTasks.get(i);
6804                // Only add calling user's recent tasks
6805                if (tr.userId != userId) continue;
6806                // Return the entry if desired by the caller.  We always return
6807                // the first entry, because callers always expect this to be the
6808                // foreground app.  We may filter others if the caller has
6809                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6810                // we should exclude the entry.
6811
6812                if (i == 0
6813                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6814                        || (tr.intent == null)
6815                        || ((tr.intent.getFlags()
6816                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6817                    ActivityManager.RecentTaskInfo rti
6818                            = new ActivityManager.RecentTaskInfo();
6819                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6820                    rti.persistentId = tr.taskId;
6821                    rti.baseIntent = new Intent(
6822                            tr.intent != null ? tr.intent : tr.affinityIntent);
6823                    if (!detailed) {
6824                        rti.baseIntent.replaceExtras((Bundle)null);
6825                    }
6826                    rti.origActivity = tr.origActivity;
6827                    rti.description = tr.lastDescription;
6828                    rti.stackId = tr.stack.mStackId;
6829
6830                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6831                        // Check whether this activity is currently available.
6832                        try {
6833                            if (rti.origActivity != null) {
6834                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6835                                        == null) {
6836                                    continue;
6837                                }
6838                            } else if (rti.baseIntent != null) {
6839                                if (pm.queryIntentActivities(rti.baseIntent,
6840                                        null, 0, userId) == null) {
6841                                    continue;
6842                                }
6843                            }
6844                        } catch (RemoteException e) {
6845                            // Will never happen.
6846                        }
6847                    }
6848
6849                    res.add(rti);
6850                    maxNum--;
6851                }
6852            }
6853            return res;
6854        }
6855    }
6856
6857    private TaskRecord recentTaskForIdLocked(int id) {
6858        final int N = mRecentTasks.size();
6859            for (int i=0; i<N; i++) {
6860                TaskRecord tr = mRecentTasks.get(i);
6861                if (tr.taskId == id) {
6862                    return tr;
6863                }
6864            }
6865            return null;
6866    }
6867
6868    @Override
6869    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6870        synchronized (this) {
6871            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6872                    "getTaskThumbnails()");
6873            TaskRecord tr = recentTaskForIdLocked(id);
6874            if (tr != null) {
6875                return tr.getTaskThumbnailsLocked();
6876            }
6877        }
6878        return null;
6879    }
6880
6881    @Override
6882    public Bitmap getTaskTopThumbnail(int id) {
6883        synchronized (this) {
6884            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6885                    "getTaskTopThumbnail()");
6886            TaskRecord tr = recentTaskForIdLocked(id);
6887            if (tr != null) {
6888                return tr.getTaskTopThumbnailLocked();
6889            }
6890        }
6891        return null;
6892    }
6893
6894    @Override
6895    public boolean removeSubTask(int taskId, int subTaskIndex) {
6896        synchronized (this) {
6897            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6898                    "removeSubTask()");
6899            long ident = Binder.clearCallingIdentity();
6900            try {
6901                TaskRecord tr = recentTaskForIdLocked(taskId);
6902                if (tr != null) {
6903                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6904                }
6905                return false;
6906            } finally {
6907                Binder.restoreCallingIdentity(ident);
6908            }
6909        }
6910    }
6911
6912    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6913        if (!pr.killedByAm) {
6914            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6915            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6916                    pr.processName, pr.setAdj, reason);
6917            pr.killedByAm = true;
6918            Process.killProcessQuiet(pr.pid);
6919        }
6920    }
6921
6922    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6923        tr.disposeThumbnail();
6924        mRecentTasks.remove(tr);
6925        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6926        Intent baseIntent = new Intent(
6927                tr.intent != null ? tr.intent : tr.affinityIntent);
6928        ComponentName component = baseIntent.getComponent();
6929        if (component == null) {
6930            Slog.w(TAG, "Now component for base intent of task: " + tr);
6931            return;
6932        }
6933
6934        // Find any running services associated with this app.
6935        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6936
6937        if (killProcesses) {
6938            // Find any running processes associated with this app.
6939            final String pkg = component.getPackageName();
6940            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6941            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6942            for (int i=0; i<pmap.size(); i++) {
6943                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6944                for (int j=0; j<uids.size(); j++) {
6945                    ProcessRecord proc = uids.valueAt(j);
6946                    if (proc.userId != tr.userId) {
6947                        continue;
6948                    }
6949                    if (!proc.pkgList.containsKey(pkg)) {
6950                        continue;
6951                    }
6952                    procs.add(proc);
6953                }
6954            }
6955
6956            // Kill the running processes.
6957            for (int i=0; i<procs.size(); i++) {
6958                ProcessRecord pr = procs.get(i);
6959                if (pr == mHomeProcess) {
6960                    // Don't kill the home process along with tasks from the same package.
6961                    continue;
6962                }
6963                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6964                    killUnneededProcessLocked(pr, "remove task");
6965                } else {
6966                    pr.waitingToKill = "remove task";
6967                }
6968            }
6969        }
6970    }
6971
6972    @Override
6973    public boolean removeTask(int taskId, int flags) {
6974        synchronized (this) {
6975            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6976                    "removeTask()");
6977            long ident = Binder.clearCallingIdentity();
6978            try {
6979                TaskRecord tr = recentTaskForIdLocked(taskId);
6980                if (tr != null) {
6981                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6982                    if (r != null) {
6983                        cleanUpRemovedTaskLocked(tr, flags);
6984                        return true;
6985                    }
6986                    if (tr.mActivities.size() == 0) {
6987                        // Caller is just removing a recent task that is
6988                        // not actively running.  That is easy!
6989                        cleanUpRemovedTaskLocked(tr, flags);
6990                        return true;
6991                    }
6992                    Slog.w(TAG, "removeTask: task " + taskId
6993                            + " does not have activities to remove, "
6994                            + " but numActivities=" + tr.numActivities
6995                            + ": " + tr);
6996                }
6997            } finally {
6998                Binder.restoreCallingIdentity(ident);
6999            }
7000        }
7001        return false;
7002    }
7003
7004    /**
7005     * TODO: Add mController hook
7006     */
7007    @Override
7008    public void moveTaskToFront(int task, int flags, Bundle options) {
7009        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7010                "moveTaskToFront()");
7011
7012        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
7013        synchronized(this) {
7014            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7015                    Binder.getCallingUid(), "Task to front")) {
7016                ActivityOptions.abort(options);
7017                return;
7018            }
7019            final long origId = Binder.clearCallingIdentity();
7020            try {
7021                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7022            } finally {
7023                Binder.restoreCallingIdentity(origId);
7024            }
7025            ActivityOptions.abort(options);
7026        }
7027    }
7028
7029    @Override
7030    public void moveTaskToBack(int taskId) {
7031        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7032                "moveTaskToBack()");
7033
7034        synchronized(this) {
7035            TaskRecord tr = recentTaskForIdLocked(taskId);
7036            if (tr != null) {
7037                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7038                ActivityStack stack = tr.stack;
7039                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7040                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7041                            Binder.getCallingUid(), "Task to back")) {
7042                        return;
7043                    }
7044                }
7045                final long origId = Binder.clearCallingIdentity();
7046                try {
7047                    stack.moveTaskToBackLocked(taskId, null);
7048                } finally {
7049                    Binder.restoreCallingIdentity(origId);
7050                }
7051            }
7052        }
7053    }
7054
7055    /**
7056     * Moves an activity, and all of the other activities within the same task, to the bottom
7057     * of the history stack.  The activity's order within the task is unchanged.
7058     *
7059     * @param token A reference to the activity we wish to move
7060     * @param nonRoot If false then this only works if the activity is the root
7061     *                of a task; if true it will work for any activity in a task.
7062     * @return Returns true if the move completed, false if not.
7063     */
7064    @Override
7065    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7066        enforceNotIsolatedCaller("moveActivityTaskToBack");
7067        synchronized(this) {
7068            final long origId = Binder.clearCallingIdentity();
7069            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7070            if (taskId >= 0) {
7071                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7072            }
7073            Binder.restoreCallingIdentity(origId);
7074        }
7075        return false;
7076    }
7077
7078    @Override
7079    public void moveTaskBackwards(int task) {
7080        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7081                "moveTaskBackwards()");
7082
7083        synchronized(this) {
7084            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7085                    Binder.getCallingUid(), "Task backwards")) {
7086                return;
7087            }
7088            final long origId = Binder.clearCallingIdentity();
7089            moveTaskBackwardsLocked(task);
7090            Binder.restoreCallingIdentity(origId);
7091        }
7092    }
7093
7094    private final void moveTaskBackwardsLocked(int task) {
7095        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7096    }
7097
7098    @Override
7099    public IBinder getHomeActivityToken() throws RemoteException {
7100        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7101                "getHomeActivityToken()");
7102        synchronized (this) {
7103            return mStackSupervisor.getHomeActivityToken();
7104        }
7105    }
7106
7107    @Override
7108    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7109            IActivityContainerCallback callback) throws RemoteException {
7110        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7111                "createActivityContainer()");
7112        synchronized (this) {
7113            if (parentActivityToken == null) {
7114                throw new IllegalArgumentException("parent token must not be null");
7115            }
7116            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7117            if (r == null) {
7118                return null;
7119            }
7120            return mStackSupervisor.createActivityContainer(r, callback);
7121        }
7122    }
7123
7124    @Override
7125    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7126        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7127                "moveTaskToStack()");
7128        if (stackId == HOME_STACK_ID) {
7129            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7130                    new RuntimeException("here").fillInStackTrace());
7131        }
7132        synchronized (this) {
7133            long ident = Binder.clearCallingIdentity();
7134            try {
7135                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7136                        + stackId + " toTop=" + toTop);
7137                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7138            } finally {
7139                Binder.restoreCallingIdentity(ident);
7140            }
7141        }
7142    }
7143
7144    @Override
7145    public void resizeStack(int stackBoxId, Rect bounds) {
7146        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7147                "resizeStackBox()");
7148        long ident = Binder.clearCallingIdentity();
7149        try {
7150            mWindowManager.resizeStack(stackBoxId, bounds);
7151        } finally {
7152            Binder.restoreCallingIdentity(ident);
7153        }
7154    }
7155
7156    @Override
7157    public List<StackInfo> getAllStackInfos() {
7158        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7159                "getAllStackInfos()");
7160        long ident = Binder.clearCallingIdentity();
7161        try {
7162            synchronized (this) {
7163                return mStackSupervisor.getAllStackInfosLocked();
7164            }
7165        } finally {
7166            Binder.restoreCallingIdentity(ident);
7167        }
7168    }
7169
7170    @Override
7171    public StackInfo getStackInfo(int stackId) {
7172        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7173                "getStackInfo()");
7174        long ident = Binder.clearCallingIdentity();
7175        try {
7176            synchronized (this) {
7177                return mStackSupervisor.getStackInfoLocked(stackId);
7178            }
7179        } finally {
7180            Binder.restoreCallingIdentity(ident);
7181        }
7182    }
7183
7184    @Override
7185    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7186        synchronized(this) {
7187            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7188        }
7189    }
7190
7191    // =========================================================
7192    // THUMBNAILS
7193    // =========================================================
7194
7195    public void reportThumbnail(IBinder token,
7196            Bitmap thumbnail, CharSequence description) {
7197        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7198        final long origId = Binder.clearCallingIdentity();
7199        sendPendingThumbnail(null, token, thumbnail, description, true);
7200        Binder.restoreCallingIdentity(origId);
7201    }
7202
7203    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7204            Bitmap thumbnail, CharSequence description, boolean always) {
7205        TaskRecord task;
7206        ArrayList<PendingThumbnailsRecord> receivers = null;
7207
7208        //System.out.println("Send pending thumbnail: " + r);
7209
7210        synchronized(this) {
7211            if (r == null) {
7212                r = ActivityRecord.isInStackLocked(token);
7213                if (r == null) {
7214                    return;
7215                }
7216            }
7217            if (thumbnail == null && r.thumbHolder != null) {
7218                thumbnail = r.thumbHolder.lastThumbnail;
7219                description = r.thumbHolder.lastDescription;
7220            }
7221            if (thumbnail == null && !always) {
7222                // If there is no thumbnail, and this entry is not actually
7223                // going away, then abort for now and pick up the next
7224                // thumbnail we get.
7225                return;
7226            }
7227            task = r.task;
7228
7229            int N = mPendingThumbnails.size();
7230            int i=0;
7231            while (i<N) {
7232                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7233                //System.out.println("Looking in " + pr.pendingRecords);
7234                if (pr.pendingRecords.remove(r)) {
7235                    if (receivers == null) {
7236                        receivers = new ArrayList<PendingThumbnailsRecord>();
7237                    }
7238                    receivers.add(pr);
7239                    if (pr.pendingRecords.size() == 0) {
7240                        pr.finished = true;
7241                        mPendingThumbnails.remove(i);
7242                        N--;
7243                        continue;
7244                    }
7245                }
7246                i++;
7247            }
7248        }
7249
7250        if (receivers != null) {
7251            final int N = receivers.size();
7252            for (int i=0; i<N; i++) {
7253                try {
7254                    PendingThumbnailsRecord pr = receivers.get(i);
7255                    pr.receiver.newThumbnail(
7256                        task != null ? task.taskId : -1, thumbnail, description);
7257                    if (pr.finished) {
7258                        pr.receiver.finished();
7259                    }
7260                } catch (Exception e) {
7261                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7262                }
7263            }
7264        }
7265    }
7266
7267    // =========================================================
7268    // CONTENT PROVIDERS
7269    // =========================================================
7270
7271    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7272        List<ProviderInfo> providers = null;
7273        try {
7274            providers = AppGlobals.getPackageManager().
7275                queryContentProviders(app.processName, app.uid,
7276                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7277        } catch (RemoteException ex) {
7278        }
7279        if (DEBUG_MU)
7280            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7281        int userId = app.userId;
7282        if (providers != null) {
7283            int N = providers.size();
7284            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7285            for (int i=0; i<N; i++) {
7286                ProviderInfo cpi =
7287                    (ProviderInfo)providers.get(i);
7288                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7289                        cpi.name, cpi.flags);
7290                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7291                    // This is a singleton provider, but a user besides the
7292                    // default user is asking to initialize a process it runs
7293                    // in...  well, no, it doesn't actually run in this process,
7294                    // it runs in the process of the default user.  Get rid of it.
7295                    providers.remove(i);
7296                    N--;
7297                    i--;
7298                    continue;
7299                }
7300
7301                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7302                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7303                if (cpr == null) {
7304                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7305                    mProviderMap.putProviderByClass(comp, cpr);
7306                }
7307                if (DEBUG_MU)
7308                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7309                app.pubProviders.put(cpi.name, cpr);
7310                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7311                    // Don't add this if it is a platform component that is marked
7312                    // to run in multiple processes, because this is actually
7313                    // part of the framework so doesn't make sense to track as a
7314                    // separate apk in the process.
7315                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7316                }
7317                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7318            }
7319        }
7320        return providers;
7321    }
7322
7323    /**
7324     * Check if {@link ProcessRecord} has a possible chance at accessing the
7325     * given {@link ProviderInfo}. Final permission checking is always done
7326     * in {@link ContentProvider}.
7327     */
7328    private final String checkContentProviderPermissionLocked(
7329            ProviderInfo cpi, ProcessRecord r) {
7330        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7331        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7332        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7333                cpi.applicationInfo.uid, cpi.exported)
7334                == PackageManager.PERMISSION_GRANTED) {
7335            return null;
7336        }
7337        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7338                cpi.applicationInfo.uid, cpi.exported)
7339                == PackageManager.PERMISSION_GRANTED) {
7340            return null;
7341        }
7342
7343        PathPermission[] pps = cpi.pathPermissions;
7344        if (pps != null) {
7345            int i = pps.length;
7346            while (i > 0) {
7347                i--;
7348                PathPermission pp = pps[i];
7349                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7350                        cpi.applicationInfo.uid, cpi.exported)
7351                        == PackageManager.PERMISSION_GRANTED) {
7352                    return null;
7353                }
7354                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7355                        cpi.applicationInfo.uid, cpi.exported)
7356                        == PackageManager.PERMISSION_GRANTED) {
7357                    return null;
7358                }
7359            }
7360        }
7361
7362        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7363        if (perms != null) {
7364            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7365                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7366                    return null;
7367                }
7368            }
7369        }
7370
7371        String msg;
7372        if (!cpi.exported) {
7373            msg = "Permission Denial: opening provider " + cpi.name
7374                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7375                    + ", uid=" + callingUid + ") that is not exported from uid "
7376                    + cpi.applicationInfo.uid;
7377        } else {
7378            msg = "Permission Denial: opening provider " + cpi.name
7379                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7380                    + ", uid=" + callingUid + ") requires "
7381                    + cpi.readPermission + " or " + cpi.writePermission;
7382        }
7383        Slog.w(TAG, msg);
7384        return msg;
7385    }
7386
7387    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7388            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7389        if (r != null) {
7390            for (int i=0; i<r.conProviders.size(); i++) {
7391                ContentProviderConnection conn = r.conProviders.get(i);
7392                if (conn.provider == cpr) {
7393                    if (DEBUG_PROVIDER) Slog.v(TAG,
7394                            "Adding provider requested by "
7395                            + r.processName + " from process "
7396                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7397                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7398                    if (stable) {
7399                        conn.stableCount++;
7400                        conn.numStableIncs++;
7401                    } else {
7402                        conn.unstableCount++;
7403                        conn.numUnstableIncs++;
7404                    }
7405                    return conn;
7406                }
7407            }
7408            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7409            if (stable) {
7410                conn.stableCount = 1;
7411                conn.numStableIncs = 1;
7412            } else {
7413                conn.unstableCount = 1;
7414                conn.numUnstableIncs = 1;
7415            }
7416            cpr.connections.add(conn);
7417            r.conProviders.add(conn);
7418            return conn;
7419        }
7420        cpr.addExternalProcessHandleLocked(externalProcessToken);
7421        return null;
7422    }
7423
7424    boolean decProviderCountLocked(ContentProviderConnection conn,
7425            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7426        if (conn != null) {
7427            cpr = conn.provider;
7428            if (DEBUG_PROVIDER) Slog.v(TAG,
7429                    "Removing provider requested by "
7430                    + conn.client.processName + " from process "
7431                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7432                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7433            if (stable) {
7434                conn.stableCount--;
7435            } else {
7436                conn.unstableCount--;
7437            }
7438            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7439                cpr.connections.remove(conn);
7440                conn.client.conProviders.remove(conn);
7441                return true;
7442            }
7443            return false;
7444        }
7445        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7446        return false;
7447    }
7448
7449    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7450            String name, IBinder token, boolean stable, int userId) {
7451        ContentProviderRecord cpr;
7452        ContentProviderConnection conn = null;
7453        ProviderInfo cpi = null;
7454
7455        synchronized(this) {
7456            ProcessRecord r = null;
7457            if (caller != null) {
7458                r = getRecordForAppLocked(caller);
7459                if (r == null) {
7460                    throw new SecurityException(
7461                            "Unable to find app for caller " + caller
7462                          + " (pid=" + Binder.getCallingPid()
7463                          + ") when getting content provider " + name);
7464                }
7465            }
7466
7467            // First check if this content provider has been published...
7468            cpr = mProviderMap.getProviderByName(name, userId);
7469            boolean providerRunning = cpr != null;
7470            if (providerRunning) {
7471                cpi = cpr.info;
7472                String msg;
7473                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7474                    throw new SecurityException(msg);
7475                }
7476
7477                if (r != null && cpr.canRunHere(r)) {
7478                    // This provider has been published or is in the process
7479                    // of being published...  but it is also allowed to run
7480                    // in the caller's process, so don't make a connection
7481                    // and just let the caller instantiate its own instance.
7482                    ContentProviderHolder holder = cpr.newHolder(null);
7483                    // don't give caller the provider object, it needs
7484                    // to make its own.
7485                    holder.provider = null;
7486                    return holder;
7487                }
7488
7489                final long origId = Binder.clearCallingIdentity();
7490
7491                // In this case the provider instance already exists, so we can
7492                // return it right away.
7493                conn = incProviderCountLocked(r, cpr, token, stable);
7494                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7495                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7496                        // If this is a perceptible app accessing the provider,
7497                        // make sure to count it as being accessed and thus
7498                        // back up on the LRU list.  This is good because
7499                        // content providers are often expensive to start.
7500                        updateLruProcessLocked(cpr.proc, false, null);
7501                    }
7502                }
7503
7504                if (cpr.proc != null) {
7505                    if (false) {
7506                        if (cpr.name.flattenToShortString().equals(
7507                                "com.android.providers.calendar/.CalendarProvider2")) {
7508                            Slog.v(TAG, "****************** KILLING "
7509                                + cpr.name.flattenToShortString());
7510                            Process.killProcess(cpr.proc.pid);
7511                        }
7512                    }
7513                    boolean success = updateOomAdjLocked(cpr.proc);
7514                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7515                    // NOTE: there is still a race here where a signal could be
7516                    // pending on the process even though we managed to update its
7517                    // adj level.  Not sure what to do about this, but at least
7518                    // the race is now smaller.
7519                    if (!success) {
7520                        // Uh oh...  it looks like the provider's process
7521                        // has been killed on us.  We need to wait for a new
7522                        // process to be started, and make sure its death
7523                        // doesn't kill our process.
7524                        Slog.i(TAG,
7525                                "Existing provider " + cpr.name.flattenToShortString()
7526                                + " is crashing; detaching " + r);
7527                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7528                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7529                        if (!lastRef) {
7530                            // This wasn't the last ref our process had on
7531                            // the provider...  we have now been killed, bail.
7532                            return null;
7533                        }
7534                        providerRunning = false;
7535                        conn = null;
7536                    }
7537                }
7538
7539                Binder.restoreCallingIdentity(origId);
7540            }
7541
7542            boolean singleton;
7543            if (!providerRunning) {
7544                try {
7545                    cpi = AppGlobals.getPackageManager().
7546                        resolveContentProvider(name,
7547                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7548                } catch (RemoteException ex) {
7549                }
7550                if (cpi == null) {
7551                    return null;
7552                }
7553                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7554                        cpi.name, cpi.flags);
7555                if (singleton) {
7556                    userId = 0;
7557                }
7558                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7559
7560                String msg;
7561                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7562                    throw new SecurityException(msg);
7563                }
7564
7565                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7566                        && !cpi.processName.equals("system")) {
7567                    // If this content provider does not run in the system
7568                    // process, and the system is not yet ready to run other
7569                    // processes, then fail fast instead of hanging.
7570                    throw new IllegalArgumentException(
7571                            "Attempt to launch content provider before system ready");
7572                }
7573
7574                // Make sure that the user who owns this provider is started.  If not,
7575                // we don't want to allow it to run.
7576                if (mStartedUsers.get(userId) == null) {
7577                    Slog.w(TAG, "Unable to launch app "
7578                            + cpi.applicationInfo.packageName + "/"
7579                            + cpi.applicationInfo.uid + " for provider "
7580                            + name + ": user " + userId + " is stopped");
7581                    return null;
7582                }
7583
7584                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7585                cpr = mProviderMap.getProviderByClass(comp, userId);
7586                final boolean firstClass = cpr == null;
7587                if (firstClass) {
7588                    try {
7589                        ApplicationInfo ai =
7590                            AppGlobals.getPackageManager().
7591                                getApplicationInfo(
7592                                        cpi.applicationInfo.packageName,
7593                                        STOCK_PM_FLAGS, userId);
7594                        if (ai == null) {
7595                            Slog.w(TAG, "No package info for content provider "
7596                                    + cpi.name);
7597                            return null;
7598                        }
7599                        ai = getAppInfoForUser(ai, userId);
7600                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7601                    } catch (RemoteException ex) {
7602                        // pm is in same process, this will never happen.
7603                    }
7604                }
7605
7606                if (r != null && cpr.canRunHere(r)) {
7607                    // If this is a multiprocess provider, then just return its
7608                    // info and allow the caller to instantiate it.  Only do
7609                    // this if the provider is the same user as the caller's
7610                    // process, or can run as root (so can be in any process).
7611                    return cpr.newHolder(null);
7612                }
7613
7614                if (DEBUG_PROVIDER) {
7615                    RuntimeException e = new RuntimeException("here");
7616                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7617                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7618                }
7619
7620                // This is single process, and our app is now connecting to it.
7621                // See if we are already in the process of launching this
7622                // provider.
7623                final int N = mLaunchingProviders.size();
7624                int i;
7625                for (i=0; i<N; i++) {
7626                    if (mLaunchingProviders.get(i) == cpr) {
7627                        break;
7628                    }
7629                }
7630
7631                // If the provider is not already being launched, then get it
7632                // started.
7633                if (i >= N) {
7634                    final long origId = Binder.clearCallingIdentity();
7635
7636                    try {
7637                        // Content provider is now in use, its package can't be stopped.
7638                        try {
7639                            AppGlobals.getPackageManager().setPackageStoppedState(
7640                                    cpr.appInfo.packageName, false, userId);
7641                        } catch (RemoteException e) {
7642                        } catch (IllegalArgumentException e) {
7643                            Slog.w(TAG, "Failed trying to unstop package "
7644                                    + cpr.appInfo.packageName + ": " + e);
7645                        }
7646
7647                        // Use existing process if already started
7648                        ProcessRecord proc = getProcessRecordLocked(
7649                                cpi.processName, cpr.appInfo.uid, false);
7650                        if (proc != null && proc.thread != null) {
7651                            if (DEBUG_PROVIDER) {
7652                                Slog.d(TAG, "Installing in existing process " + proc);
7653                            }
7654                            proc.pubProviders.put(cpi.name, cpr);
7655                            try {
7656                                proc.thread.scheduleInstallProvider(cpi);
7657                            } catch (RemoteException e) {
7658                            }
7659                        } else {
7660                            proc = startProcessLocked(cpi.processName,
7661                                    cpr.appInfo, false, 0, "content provider",
7662                                    new ComponentName(cpi.applicationInfo.packageName,
7663                                            cpi.name), false, false, false);
7664                            if (proc == null) {
7665                                Slog.w(TAG, "Unable to launch app "
7666                                        + cpi.applicationInfo.packageName + "/"
7667                                        + cpi.applicationInfo.uid + " for provider "
7668                                        + name + ": process is bad");
7669                                return null;
7670                            }
7671                        }
7672                        cpr.launchingApp = proc;
7673                        mLaunchingProviders.add(cpr);
7674                    } finally {
7675                        Binder.restoreCallingIdentity(origId);
7676                    }
7677                }
7678
7679                // Make sure the provider is published (the same provider class
7680                // may be published under multiple names).
7681                if (firstClass) {
7682                    mProviderMap.putProviderByClass(comp, cpr);
7683                }
7684
7685                mProviderMap.putProviderByName(name, cpr);
7686                conn = incProviderCountLocked(r, cpr, token, stable);
7687                if (conn != null) {
7688                    conn.waiting = true;
7689                }
7690            }
7691        }
7692
7693        // Wait for the provider to be published...
7694        synchronized (cpr) {
7695            while (cpr.provider == null) {
7696                if (cpr.launchingApp == null) {
7697                    Slog.w(TAG, "Unable to launch app "
7698                            + cpi.applicationInfo.packageName + "/"
7699                            + cpi.applicationInfo.uid + " for provider "
7700                            + name + ": launching app became null");
7701                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7702                            UserHandle.getUserId(cpi.applicationInfo.uid),
7703                            cpi.applicationInfo.packageName,
7704                            cpi.applicationInfo.uid, name);
7705                    return null;
7706                }
7707                try {
7708                    if (DEBUG_MU) {
7709                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7710                                + cpr.launchingApp);
7711                    }
7712                    if (conn != null) {
7713                        conn.waiting = true;
7714                    }
7715                    cpr.wait();
7716                } catch (InterruptedException ex) {
7717                } finally {
7718                    if (conn != null) {
7719                        conn.waiting = false;
7720                    }
7721                }
7722            }
7723        }
7724        return cpr != null ? cpr.newHolder(conn) : null;
7725    }
7726
7727    public final ContentProviderHolder getContentProvider(
7728            IApplicationThread caller, String name, int userId, boolean stable) {
7729        enforceNotIsolatedCaller("getContentProvider");
7730        if (caller == null) {
7731            String msg = "null IApplicationThread when getting content provider "
7732                    + name;
7733            Slog.w(TAG, msg);
7734            throw new SecurityException(msg);
7735        }
7736
7737        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7738                false, true, "getContentProvider", null);
7739        return getContentProviderImpl(caller, name, null, stable, userId);
7740    }
7741
7742    public ContentProviderHolder getContentProviderExternal(
7743            String name, int userId, IBinder token) {
7744        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7745            "Do not have permission in call getContentProviderExternal()");
7746        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7747                false, true, "getContentProvider", null);
7748        return getContentProviderExternalUnchecked(name, token, userId);
7749    }
7750
7751    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7752            IBinder token, int userId) {
7753        return getContentProviderImpl(null, name, token, true, userId);
7754    }
7755
7756    /**
7757     * Drop a content provider from a ProcessRecord's bookkeeping
7758     */
7759    public void removeContentProvider(IBinder connection, boolean stable) {
7760        enforceNotIsolatedCaller("removeContentProvider");
7761        synchronized (this) {
7762            ContentProviderConnection conn;
7763            try {
7764                conn = (ContentProviderConnection)connection;
7765            } catch (ClassCastException e) {
7766                String msg ="removeContentProvider: " + connection
7767                        + " not a ContentProviderConnection";
7768                Slog.w(TAG, msg);
7769                throw new IllegalArgumentException(msg);
7770            }
7771            if (conn == null) {
7772                throw new NullPointerException("connection is null");
7773            }
7774            if (decProviderCountLocked(conn, null, null, stable)) {
7775                updateOomAdjLocked();
7776            }
7777        }
7778    }
7779
7780    public void removeContentProviderExternal(String name, IBinder token) {
7781        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7782            "Do not have permission in call removeContentProviderExternal()");
7783        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7784    }
7785
7786    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7787        synchronized (this) {
7788            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7789            if(cpr == null) {
7790                //remove from mProvidersByClass
7791                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7792                return;
7793            }
7794
7795            //update content provider record entry info
7796            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7797            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7798            if (localCpr.hasExternalProcessHandles()) {
7799                if (localCpr.removeExternalProcessHandleLocked(token)) {
7800                    updateOomAdjLocked();
7801                } else {
7802                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7803                            + " with no external reference for token: "
7804                            + token + ".");
7805                }
7806            } else {
7807                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7808                        + " with no external references.");
7809            }
7810        }
7811    }
7812
7813    public final void publishContentProviders(IApplicationThread caller,
7814            List<ContentProviderHolder> providers) {
7815        if (providers == null) {
7816            return;
7817        }
7818
7819        enforceNotIsolatedCaller("publishContentProviders");
7820        synchronized (this) {
7821            final ProcessRecord r = getRecordForAppLocked(caller);
7822            if (DEBUG_MU)
7823                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7824            if (r == null) {
7825                throw new SecurityException(
7826                        "Unable to find app for caller " + caller
7827                      + " (pid=" + Binder.getCallingPid()
7828                      + ") when publishing content providers");
7829            }
7830
7831            final long origId = Binder.clearCallingIdentity();
7832
7833            final int N = providers.size();
7834            for (int i=0; i<N; i++) {
7835                ContentProviderHolder src = providers.get(i);
7836                if (src == null || src.info == null || src.provider == null) {
7837                    continue;
7838                }
7839                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7840                if (DEBUG_MU)
7841                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7842                if (dst != null) {
7843                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7844                    mProviderMap.putProviderByClass(comp, dst);
7845                    String names[] = dst.info.authority.split(";");
7846                    for (int j = 0; j < names.length; j++) {
7847                        mProviderMap.putProviderByName(names[j], dst);
7848                    }
7849
7850                    int NL = mLaunchingProviders.size();
7851                    int j;
7852                    for (j=0; j<NL; j++) {
7853                        if (mLaunchingProviders.get(j) == dst) {
7854                            mLaunchingProviders.remove(j);
7855                            j--;
7856                            NL--;
7857                        }
7858                    }
7859                    synchronized (dst) {
7860                        dst.provider = src.provider;
7861                        dst.proc = r;
7862                        dst.notifyAll();
7863                    }
7864                    updateOomAdjLocked(r);
7865                }
7866            }
7867
7868            Binder.restoreCallingIdentity(origId);
7869        }
7870    }
7871
7872    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7873        ContentProviderConnection conn;
7874        try {
7875            conn = (ContentProviderConnection)connection;
7876        } catch (ClassCastException e) {
7877            String msg ="refContentProvider: " + connection
7878                    + " not a ContentProviderConnection";
7879            Slog.w(TAG, msg);
7880            throw new IllegalArgumentException(msg);
7881        }
7882        if (conn == null) {
7883            throw new NullPointerException("connection is null");
7884        }
7885
7886        synchronized (this) {
7887            if (stable > 0) {
7888                conn.numStableIncs += stable;
7889            }
7890            stable = conn.stableCount + stable;
7891            if (stable < 0) {
7892                throw new IllegalStateException("stableCount < 0: " + stable);
7893            }
7894
7895            if (unstable > 0) {
7896                conn.numUnstableIncs += unstable;
7897            }
7898            unstable = conn.unstableCount + unstable;
7899            if (unstable < 0) {
7900                throw new IllegalStateException("unstableCount < 0: " + unstable);
7901            }
7902
7903            if ((stable+unstable) <= 0) {
7904                throw new IllegalStateException("ref counts can't go to zero here: stable="
7905                        + stable + " unstable=" + unstable);
7906            }
7907            conn.stableCount = stable;
7908            conn.unstableCount = unstable;
7909            return !conn.dead;
7910        }
7911    }
7912
7913    public void unstableProviderDied(IBinder connection) {
7914        ContentProviderConnection conn;
7915        try {
7916            conn = (ContentProviderConnection)connection;
7917        } catch (ClassCastException e) {
7918            String msg ="refContentProvider: " + connection
7919                    + " not a ContentProviderConnection";
7920            Slog.w(TAG, msg);
7921            throw new IllegalArgumentException(msg);
7922        }
7923        if (conn == null) {
7924            throw new NullPointerException("connection is null");
7925        }
7926
7927        // Safely retrieve the content provider associated with the connection.
7928        IContentProvider provider;
7929        synchronized (this) {
7930            provider = conn.provider.provider;
7931        }
7932
7933        if (provider == null) {
7934            // Um, yeah, we're way ahead of you.
7935            return;
7936        }
7937
7938        // Make sure the caller is being honest with us.
7939        if (provider.asBinder().pingBinder()) {
7940            // Er, no, still looks good to us.
7941            synchronized (this) {
7942                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7943                        + " says " + conn + " died, but we don't agree");
7944                return;
7945            }
7946        }
7947
7948        // Well look at that!  It's dead!
7949        synchronized (this) {
7950            if (conn.provider.provider != provider) {
7951                // But something changed...  good enough.
7952                return;
7953            }
7954
7955            ProcessRecord proc = conn.provider.proc;
7956            if (proc == null || proc.thread == null) {
7957                // Seems like the process is already cleaned up.
7958                return;
7959            }
7960
7961            // As far as we're concerned, this is just like receiving a
7962            // death notification...  just a bit prematurely.
7963            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7964                    + ") early provider death");
7965            final long ident = Binder.clearCallingIdentity();
7966            try {
7967                appDiedLocked(proc, proc.pid, proc.thread);
7968            } finally {
7969                Binder.restoreCallingIdentity(ident);
7970            }
7971        }
7972    }
7973
7974    @Override
7975    public void appNotRespondingViaProvider(IBinder connection) {
7976        enforceCallingPermission(
7977                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7978
7979        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7980        if (conn == null) {
7981            Slog.w(TAG, "ContentProviderConnection is null");
7982            return;
7983        }
7984
7985        final ProcessRecord host = conn.provider.proc;
7986        if (host == null) {
7987            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7988            return;
7989        }
7990
7991        final long token = Binder.clearCallingIdentity();
7992        try {
7993            appNotResponding(host, null, null, false, "ContentProvider not responding");
7994        } finally {
7995            Binder.restoreCallingIdentity(token);
7996        }
7997    }
7998
7999    public static final void installSystemProviders() {
8000        List<ProviderInfo> providers;
8001        synchronized (mSelf) {
8002            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
8003            providers = mSelf.generateApplicationProvidersLocked(app);
8004            if (providers != null) {
8005                for (int i=providers.size()-1; i>=0; i--) {
8006                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8007                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8008                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8009                                + ": not system .apk");
8010                        providers.remove(i);
8011                    }
8012                }
8013            }
8014        }
8015        if (providers != null) {
8016            mSystemThread.installSystemProviders(providers);
8017        }
8018
8019        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
8020
8021        mSelf.mUsageStatsService.monitorPackages();
8022    }
8023
8024    /**
8025     * Allows app to retrieve the MIME type of a URI without having permission
8026     * to access its content provider.
8027     *
8028     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8029     *
8030     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8031     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8032     */
8033    public String getProviderMimeType(Uri uri, int userId) {
8034        enforceNotIsolatedCaller("getProviderMimeType");
8035        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8036                userId, false, true, "getProviderMimeType", null);
8037        final String name = uri.getAuthority();
8038        final long ident = Binder.clearCallingIdentity();
8039        ContentProviderHolder holder = null;
8040
8041        try {
8042            holder = getContentProviderExternalUnchecked(name, null, userId);
8043            if (holder != null) {
8044                return holder.provider.getType(uri);
8045            }
8046        } catch (RemoteException e) {
8047            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8048            return null;
8049        } finally {
8050            if (holder != null) {
8051                removeContentProviderExternalUnchecked(name, null, userId);
8052            }
8053            Binder.restoreCallingIdentity(ident);
8054        }
8055
8056        return null;
8057    }
8058
8059    // =========================================================
8060    // GLOBAL MANAGEMENT
8061    // =========================================================
8062
8063    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8064            boolean isolated) {
8065        String proc = customProcess != null ? customProcess : info.processName;
8066        BatteryStatsImpl.Uid.Proc ps = null;
8067        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8068        int uid = info.uid;
8069        if (isolated) {
8070            int userId = UserHandle.getUserId(uid);
8071            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8072            while (true) {
8073                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8074                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8075                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8076                }
8077                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8078                mNextIsolatedProcessUid++;
8079                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8080                    // No process for this uid, use it.
8081                    break;
8082                }
8083                stepsLeft--;
8084                if (stepsLeft <= 0) {
8085                    return null;
8086                }
8087            }
8088        }
8089        return new ProcessRecord(stats, info, proc, uid);
8090    }
8091
8092    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8093        ProcessRecord app;
8094        if (!isolated) {
8095            app = getProcessRecordLocked(info.processName, info.uid, true);
8096        } else {
8097            app = null;
8098        }
8099
8100        if (app == null) {
8101            app = newProcessRecordLocked(info, null, isolated);
8102            mProcessNames.put(info.processName, app.uid, app);
8103            if (isolated) {
8104                mIsolatedProcesses.put(app.uid, app);
8105            }
8106            updateLruProcessLocked(app, false, null);
8107            updateOomAdjLocked();
8108        }
8109
8110        // This package really, really can not be stopped.
8111        try {
8112            AppGlobals.getPackageManager().setPackageStoppedState(
8113                    info.packageName, false, UserHandle.getUserId(app.uid));
8114        } catch (RemoteException e) {
8115        } catch (IllegalArgumentException e) {
8116            Slog.w(TAG, "Failed trying to unstop package "
8117                    + info.packageName + ": " + e);
8118        }
8119
8120        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8121                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8122            app.persistent = true;
8123            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8124        }
8125        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8126            mPersistentStartingProcesses.add(app);
8127            startProcessLocked(app, "added application", app.processName);
8128        }
8129
8130        return app;
8131    }
8132
8133    public void unhandledBack() {
8134        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8135                "unhandledBack()");
8136
8137        synchronized(this) {
8138            final long origId = Binder.clearCallingIdentity();
8139            try {
8140                getFocusedStack().unhandledBackLocked();
8141            } finally {
8142                Binder.restoreCallingIdentity(origId);
8143            }
8144        }
8145    }
8146
8147    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8148        enforceNotIsolatedCaller("openContentUri");
8149        final int userId = UserHandle.getCallingUserId();
8150        String name = uri.getAuthority();
8151        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8152        ParcelFileDescriptor pfd = null;
8153        if (cph != null) {
8154            // We record the binder invoker's uid in thread-local storage before
8155            // going to the content provider to open the file.  Later, in the code
8156            // that handles all permissions checks, we look for this uid and use
8157            // that rather than the Activity Manager's own uid.  The effect is that
8158            // we do the check against the caller's permissions even though it looks
8159            // to the content provider like the Activity Manager itself is making
8160            // the request.
8161            sCallerIdentity.set(new Identity(
8162                    Binder.getCallingPid(), Binder.getCallingUid()));
8163            try {
8164                pfd = cph.provider.openFile(null, uri, "r", null);
8165            } catch (FileNotFoundException e) {
8166                // do nothing; pfd will be returned null
8167            } finally {
8168                // Ensure that whatever happens, we clean up the identity state
8169                sCallerIdentity.remove();
8170            }
8171
8172            // We've got the fd now, so we're done with the provider.
8173            removeContentProviderExternalUnchecked(name, null, userId);
8174        } else {
8175            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8176        }
8177        return pfd;
8178    }
8179
8180    // Actually is sleeping or shutting down or whatever else in the future
8181    // is an inactive state.
8182    public boolean isSleepingOrShuttingDown() {
8183        return mSleeping || mShuttingDown;
8184    }
8185
8186    public void goingToSleep() {
8187        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8188                != PackageManager.PERMISSION_GRANTED) {
8189            throw new SecurityException("Requires permission "
8190                    + android.Manifest.permission.DEVICE_POWER);
8191        }
8192
8193        synchronized(this) {
8194            mWentToSleep = true;
8195            updateEventDispatchingLocked();
8196
8197            if (!mSleeping) {
8198                mSleeping = true;
8199                mStackSupervisor.goingToSleepLocked();
8200
8201                // Initialize the wake times of all processes.
8202                checkExcessivePowerUsageLocked(false);
8203                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8204                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8205                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8206            }
8207        }
8208    }
8209
8210    @Override
8211    public boolean shutdown(int timeout) {
8212        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8213                != PackageManager.PERMISSION_GRANTED) {
8214            throw new SecurityException("Requires permission "
8215                    + android.Manifest.permission.SHUTDOWN);
8216        }
8217
8218        boolean timedout = false;
8219
8220        synchronized(this) {
8221            mShuttingDown = true;
8222            updateEventDispatchingLocked();
8223            timedout = mStackSupervisor.shutdownLocked(timeout);
8224        }
8225
8226        mAppOpsService.shutdown();
8227        mUsageStatsService.shutdown();
8228        mBatteryStatsService.shutdown();
8229        synchronized (this) {
8230            mProcessStats.shutdownLocked();
8231        }
8232
8233        return timedout;
8234    }
8235
8236    public final void activitySlept(IBinder token) {
8237        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8238
8239        final long origId = Binder.clearCallingIdentity();
8240
8241        synchronized (this) {
8242            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8243            if (r != null) {
8244                mStackSupervisor.activitySleptLocked(r);
8245            }
8246        }
8247
8248        Binder.restoreCallingIdentity(origId);
8249    }
8250
8251    void logLockScreen(String msg) {
8252        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8253                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8254                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8255                mStackSupervisor.mDismissKeyguardOnNextActivity);
8256    }
8257
8258    private void comeOutOfSleepIfNeededLocked() {
8259        if (!mWentToSleep && !mLockScreenShown) {
8260            if (mSleeping) {
8261                mSleeping = false;
8262                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8263            }
8264        }
8265    }
8266
8267    public void wakingUp() {
8268        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8269                != PackageManager.PERMISSION_GRANTED) {
8270            throw new SecurityException("Requires permission "
8271                    + android.Manifest.permission.DEVICE_POWER);
8272        }
8273
8274        synchronized(this) {
8275            mWentToSleep = false;
8276            updateEventDispatchingLocked();
8277            comeOutOfSleepIfNeededLocked();
8278        }
8279    }
8280
8281    private void updateEventDispatchingLocked() {
8282        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8283    }
8284
8285    public void setLockScreenShown(boolean shown) {
8286        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8287                != PackageManager.PERMISSION_GRANTED) {
8288            throw new SecurityException("Requires permission "
8289                    + android.Manifest.permission.DEVICE_POWER);
8290        }
8291
8292        synchronized(this) {
8293            long ident = Binder.clearCallingIdentity();
8294            try {
8295                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8296                mLockScreenShown = shown;
8297                comeOutOfSleepIfNeededLocked();
8298            } finally {
8299                Binder.restoreCallingIdentity(ident);
8300            }
8301        }
8302    }
8303
8304    public void stopAppSwitches() {
8305        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8306                != PackageManager.PERMISSION_GRANTED) {
8307            throw new SecurityException("Requires permission "
8308                    + android.Manifest.permission.STOP_APP_SWITCHES);
8309        }
8310
8311        synchronized(this) {
8312            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8313                    + APP_SWITCH_DELAY_TIME;
8314            mDidAppSwitch = false;
8315            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8316            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8317            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8318        }
8319    }
8320
8321    public void resumeAppSwitches() {
8322        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8323                != PackageManager.PERMISSION_GRANTED) {
8324            throw new SecurityException("Requires permission "
8325                    + android.Manifest.permission.STOP_APP_SWITCHES);
8326        }
8327
8328        synchronized(this) {
8329            // Note that we don't execute any pending app switches... we will
8330            // let those wait until either the timeout, or the next start
8331            // activity request.
8332            mAppSwitchesAllowedTime = 0;
8333        }
8334    }
8335
8336    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8337            String name) {
8338        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8339            return true;
8340        }
8341
8342        final int perm = checkComponentPermission(
8343                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8344                callingUid, -1, true);
8345        if (perm == PackageManager.PERMISSION_GRANTED) {
8346            return true;
8347        }
8348
8349        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8350        return false;
8351    }
8352
8353    public void setDebugApp(String packageName, boolean waitForDebugger,
8354            boolean persistent) {
8355        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8356                "setDebugApp()");
8357
8358        long ident = Binder.clearCallingIdentity();
8359        try {
8360            // Note that this is not really thread safe if there are multiple
8361            // callers into it at the same time, but that's not a situation we
8362            // care about.
8363            if (persistent) {
8364                final ContentResolver resolver = mContext.getContentResolver();
8365                Settings.Global.putString(
8366                    resolver, Settings.Global.DEBUG_APP,
8367                    packageName);
8368                Settings.Global.putInt(
8369                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8370                    waitForDebugger ? 1 : 0);
8371            }
8372
8373            synchronized (this) {
8374                if (!persistent) {
8375                    mOrigDebugApp = mDebugApp;
8376                    mOrigWaitForDebugger = mWaitForDebugger;
8377                }
8378                mDebugApp = packageName;
8379                mWaitForDebugger = waitForDebugger;
8380                mDebugTransient = !persistent;
8381                if (packageName != null) {
8382                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8383                            UserHandle.USER_ALL, "set debug app");
8384                }
8385            }
8386        } finally {
8387            Binder.restoreCallingIdentity(ident);
8388        }
8389    }
8390
8391    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8392        synchronized (this) {
8393            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8394            if (!isDebuggable) {
8395                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8396                    throw new SecurityException("Process not debuggable: " + app.packageName);
8397                }
8398            }
8399
8400            mOpenGlTraceApp = processName;
8401        }
8402    }
8403
8404    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8405            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8406        synchronized (this) {
8407            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8408            if (!isDebuggable) {
8409                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8410                    throw new SecurityException("Process not debuggable: " + app.packageName);
8411                }
8412            }
8413            mProfileApp = processName;
8414            mProfileFile = profileFile;
8415            if (mProfileFd != null) {
8416                try {
8417                    mProfileFd.close();
8418                } catch (IOException e) {
8419                }
8420                mProfileFd = null;
8421            }
8422            mProfileFd = profileFd;
8423            mProfileType = 0;
8424            mAutoStopProfiler = autoStopProfiler;
8425        }
8426    }
8427
8428    @Override
8429    public void setAlwaysFinish(boolean enabled) {
8430        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8431                "setAlwaysFinish()");
8432
8433        Settings.Global.putInt(
8434                mContext.getContentResolver(),
8435                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8436
8437        synchronized (this) {
8438            mAlwaysFinishActivities = enabled;
8439        }
8440    }
8441
8442    @Override
8443    public void setActivityController(IActivityController controller) {
8444        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8445                "setActivityController()");
8446        synchronized (this) {
8447            mController = controller;
8448            Watchdog.getInstance().setActivityController(controller);
8449        }
8450    }
8451
8452    @Override
8453    public void setUserIsMonkey(boolean userIsMonkey) {
8454        synchronized (this) {
8455            synchronized (mPidsSelfLocked) {
8456                final int callingPid = Binder.getCallingPid();
8457                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8458                if (precessRecord == null) {
8459                    throw new SecurityException("Unknown process: " + callingPid);
8460                }
8461                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8462                    throw new SecurityException("Only an instrumentation process "
8463                            + "with a UiAutomation can call setUserIsMonkey");
8464                }
8465            }
8466            mUserIsMonkey = userIsMonkey;
8467        }
8468    }
8469
8470    @Override
8471    public boolean isUserAMonkey() {
8472        synchronized (this) {
8473            // If there is a controller also implies the user is a monkey.
8474            return (mUserIsMonkey || mController != null);
8475        }
8476    }
8477
8478    public void requestBugReport() {
8479        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8480        SystemProperties.set("ctl.start", "bugreport");
8481    }
8482
8483    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8484        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8485    }
8486
8487    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8488        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8489            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8490        }
8491        return KEY_DISPATCHING_TIMEOUT;
8492    }
8493
8494    @Override
8495    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8496        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8497                != PackageManager.PERMISSION_GRANTED) {
8498            throw new SecurityException("Requires permission "
8499                    + android.Manifest.permission.FILTER_EVENTS);
8500        }
8501        ProcessRecord proc;
8502        long timeout;
8503        synchronized (this) {
8504            synchronized (mPidsSelfLocked) {
8505                proc = mPidsSelfLocked.get(pid);
8506            }
8507            timeout = getInputDispatchingTimeoutLocked(proc);
8508        }
8509
8510        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8511            return -1;
8512        }
8513
8514        return timeout;
8515    }
8516
8517    /**
8518     * Handle input dispatching timeouts.
8519     * Returns whether input dispatching should be aborted or not.
8520     */
8521    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8522            final ActivityRecord activity, final ActivityRecord parent,
8523            final boolean aboveSystem, String reason) {
8524        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8525                != PackageManager.PERMISSION_GRANTED) {
8526            throw new SecurityException("Requires permission "
8527                    + android.Manifest.permission.FILTER_EVENTS);
8528        }
8529
8530        final String annotation;
8531        if (reason == null) {
8532            annotation = "Input dispatching timed out";
8533        } else {
8534            annotation = "Input dispatching timed out (" + reason + ")";
8535        }
8536
8537        if (proc != null) {
8538            synchronized (this) {
8539                if (proc.debugging) {
8540                    return false;
8541                }
8542
8543                if (mDidDexOpt) {
8544                    // Give more time since we were dexopting.
8545                    mDidDexOpt = false;
8546                    return false;
8547                }
8548
8549                if (proc.instrumentationClass != null) {
8550                    Bundle info = new Bundle();
8551                    info.putString("shortMsg", "keyDispatchingTimedOut");
8552                    info.putString("longMsg", annotation);
8553                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8554                    return true;
8555                }
8556            }
8557            mHandler.post(new Runnable() {
8558                @Override
8559                public void run() {
8560                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8561                }
8562            });
8563        }
8564
8565        return true;
8566    }
8567
8568    public Bundle getAssistContextExtras(int requestType) {
8569        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8570                "getAssistContextExtras()");
8571        PendingAssistExtras pae;
8572        Bundle extras = new Bundle();
8573        synchronized (this) {
8574            ActivityRecord activity = getFocusedStack().mResumedActivity;
8575            if (activity == null) {
8576                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8577                return null;
8578            }
8579            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8580            if (activity.app == null || activity.app.thread == null) {
8581                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8582                return extras;
8583            }
8584            if (activity.app.pid == Binder.getCallingPid()) {
8585                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8586                return extras;
8587            }
8588            pae = new PendingAssistExtras(activity);
8589            try {
8590                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8591                        requestType);
8592                mPendingAssistExtras.add(pae);
8593                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8594            } catch (RemoteException e) {
8595                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8596                return extras;
8597            }
8598        }
8599        synchronized (pae) {
8600            while (!pae.haveResult) {
8601                try {
8602                    pae.wait();
8603                } catch (InterruptedException e) {
8604                }
8605            }
8606            if (pae.result != null) {
8607                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8608            }
8609        }
8610        synchronized (this) {
8611            mPendingAssistExtras.remove(pae);
8612            mHandler.removeCallbacks(pae);
8613        }
8614        return extras;
8615    }
8616
8617    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8618        PendingAssistExtras pae = (PendingAssistExtras)token;
8619        synchronized (pae) {
8620            pae.result = extras;
8621            pae.haveResult = true;
8622            pae.notifyAll();
8623        }
8624    }
8625
8626    public void registerProcessObserver(IProcessObserver observer) {
8627        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8628                "registerProcessObserver()");
8629        synchronized (this) {
8630            mProcessObservers.register(observer);
8631        }
8632    }
8633
8634    @Override
8635    public void unregisterProcessObserver(IProcessObserver observer) {
8636        synchronized (this) {
8637            mProcessObservers.unregister(observer);
8638        }
8639    }
8640
8641    @Override
8642    public boolean convertFromTranslucent(IBinder token) {
8643        final long origId = Binder.clearCallingIdentity();
8644        try {
8645            synchronized (this) {
8646                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8647                if (r == null) {
8648                    return false;
8649                }
8650                if (r.changeWindowTranslucency(true)) {
8651                    mWindowManager.setAppFullscreen(token, true);
8652                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8653                    return true;
8654                }
8655                return false;
8656            }
8657        } finally {
8658            Binder.restoreCallingIdentity(origId);
8659        }
8660    }
8661
8662    @Override
8663    public boolean convertToTranslucent(IBinder token) {
8664        final long origId = Binder.clearCallingIdentity();
8665        try {
8666            synchronized (this) {
8667                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8668                if (r == null) {
8669                    return false;
8670                }
8671                if (r.changeWindowTranslucency(false)) {
8672                    r.task.stack.convertToTranslucent(r);
8673                    mWindowManager.setAppFullscreen(token, false);
8674                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8675                    return true;
8676                }
8677                return false;
8678            }
8679        } finally {
8680            Binder.restoreCallingIdentity(origId);
8681        }
8682    }
8683
8684    @Override
8685    public void setImmersive(IBinder token, boolean immersive) {
8686        synchronized(this) {
8687            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8688            if (r == null) {
8689                throw new IllegalArgumentException();
8690            }
8691            r.immersive = immersive;
8692
8693            // update associated state if we're frontmost
8694            if (r == mFocusedActivity) {
8695                if (DEBUG_IMMERSIVE) {
8696                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8697                }
8698                applyUpdateLockStateLocked(r);
8699            }
8700        }
8701    }
8702
8703    @Override
8704    public boolean isImmersive(IBinder token) {
8705        synchronized (this) {
8706            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8707            if (r == null) {
8708                throw new IllegalArgumentException();
8709            }
8710            return r.immersive;
8711        }
8712    }
8713
8714    public boolean isTopActivityImmersive() {
8715        enforceNotIsolatedCaller("startActivity");
8716        synchronized (this) {
8717            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8718            return (r != null) ? r.immersive : false;
8719        }
8720    }
8721
8722    public final void enterSafeMode() {
8723        synchronized(this) {
8724            // It only makes sense to do this before the system is ready
8725            // and started launching other packages.
8726            if (!mSystemReady) {
8727                try {
8728                    AppGlobals.getPackageManager().enterSafeMode();
8729                } catch (RemoteException e) {
8730                }
8731            }
8732        }
8733    }
8734
8735    public final void showSafeModeOverlay() {
8736        View v = LayoutInflater.from(mContext).inflate(
8737                com.android.internal.R.layout.safe_mode, null);
8738        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8739        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8740        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8741        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8742        lp.gravity = Gravity.BOTTOM | Gravity.START;
8743        lp.format = v.getBackground().getOpacity();
8744        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8745                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8746        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8747        ((WindowManager)mContext.getSystemService(
8748                Context.WINDOW_SERVICE)).addView(v, lp);
8749    }
8750
8751    public void noteWakeupAlarm(IIntentSender sender) {
8752        if (!(sender instanceof PendingIntentRecord)) {
8753            return;
8754        }
8755        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8756        synchronized (stats) {
8757            if (mBatteryStatsService.isOnBattery()) {
8758                mBatteryStatsService.enforceCallingPermission();
8759                PendingIntentRecord rec = (PendingIntentRecord)sender;
8760                int MY_UID = Binder.getCallingUid();
8761                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8762                BatteryStatsImpl.Uid.Pkg pkg =
8763                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8764                pkg.incWakeupsLocked();
8765            }
8766        }
8767    }
8768
8769    public boolean killPids(int[] pids, String pReason, boolean secure) {
8770        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8771            throw new SecurityException("killPids only available to the system");
8772        }
8773        String reason = (pReason == null) ? "Unknown" : pReason;
8774        // XXX Note: don't acquire main activity lock here, because the window
8775        // manager calls in with its locks held.
8776
8777        boolean killed = false;
8778        synchronized (mPidsSelfLocked) {
8779            int[] types = new int[pids.length];
8780            int worstType = 0;
8781            for (int i=0; i<pids.length; i++) {
8782                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8783                if (proc != null) {
8784                    int type = proc.setAdj;
8785                    types[i] = type;
8786                    if (type > worstType) {
8787                        worstType = type;
8788                    }
8789                }
8790            }
8791
8792            // If the worst oom_adj is somewhere in the cached proc LRU range,
8793            // then constrain it so we will kill all cached procs.
8794            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8795                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8796                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8797            }
8798
8799            // If this is not a secure call, don't let it kill processes that
8800            // are important.
8801            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8802                worstType = ProcessList.SERVICE_ADJ;
8803            }
8804
8805            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8806            for (int i=0; i<pids.length; i++) {
8807                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8808                if (proc == null) {
8809                    continue;
8810                }
8811                int adj = proc.setAdj;
8812                if (adj >= worstType && !proc.killedByAm) {
8813                    killUnneededProcessLocked(proc, reason);
8814                    killed = true;
8815                }
8816            }
8817        }
8818        return killed;
8819    }
8820
8821    @Override
8822    public void killUid(int uid, String reason) {
8823        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8824            throw new SecurityException("killUid only available to the system");
8825        }
8826        synchronized (this) {
8827            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8828                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8829                    reason != null ? reason : "kill uid");
8830        }
8831    }
8832
8833    @Override
8834    public boolean killProcessesBelowForeground(String reason) {
8835        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8836            throw new SecurityException("killProcessesBelowForeground() only available to system");
8837        }
8838
8839        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8840    }
8841
8842    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8843        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8844            throw new SecurityException("killProcessesBelowAdj() only available to system");
8845        }
8846
8847        boolean killed = false;
8848        synchronized (mPidsSelfLocked) {
8849            final int size = mPidsSelfLocked.size();
8850            for (int i = 0; i < size; i++) {
8851                final int pid = mPidsSelfLocked.keyAt(i);
8852                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8853                if (proc == null) continue;
8854
8855                final int adj = proc.setAdj;
8856                if (adj > belowAdj && !proc.killedByAm) {
8857                    killUnneededProcessLocked(proc, reason);
8858                    killed = true;
8859                }
8860            }
8861        }
8862        return killed;
8863    }
8864
8865    @Override
8866    public void hang(final IBinder who, boolean allowRestart) {
8867        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8868                != PackageManager.PERMISSION_GRANTED) {
8869            throw new SecurityException("Requires permission "
8870                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8871        }
8872
8873        final IBinder.DeathRecipient death = new DeathRecipient() {
8874            @Override
8875            public void binderDied() {
8876                synchronized (this) {
8877                    notifyAll();
8878                }
8879            }
8880        };
8881
8882        try {
8883            who.linkToDeath(death, 0);
8884        } catch (RemoteException e) {
8885            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8886            return;
8887        }
8888
8889        synchronized (this) {
8890            Watchdog.getInstance().setAllowRestart(allowRestart);
8891            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8892            synchronized (death) {
8893                while (who.isBinderAlive()) {
8894                    try {
8895                        death.wait();
8896                    } catch (InterruptedException e) {
8897                    }
8898                }
8899            }
8900            Watchdog.getInstance().setAllowRestart(true);
8901        }
8902    }
8903
8904    @Override
8905    public void restart() {
8906        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8907                != PackageManager.PERMISSION_GRANTED) {
8908            throw new SecurityException("Requires permission "
8909                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8910        }
8911
8912        Log.i(TAG, "Sending shutdown broadcast...");
8913
8914        BroadcastReceiver br = new BroadcastReceiver() {
8915            @Override public void onReceive(Context context, Intent intent) {
8916                // Now the broadcast is done, finish up the low-level shutdown.
8917                Log.i(TAG, "Shutting down activity manager...");
8918                shutdown(10000);
8919                Log.i(TAG, "Shutdown complete, restarting!");
8920                Process.killProcess(Process.myPid());
8921                System.exit(10);
8922            }
8923        };
8924
8925        // First send the high-level shut down broadcast.
8926        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8927        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8928        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8929        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8930        mContext.sendOrderedBroadcastAsUser(intent,
8931                UserHandle.ALL, null, br, mHandler, 0, null, null);
8932        */
8933        br.onReceive(mContext, intent);
8934    }
8935
8936    private long getLowRamTimeSinceIdle(long now) {
8937        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8938    }
8939
8940    @Override
8941    public void performIdleMaintenance() {
8942        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8943                != PackageManager.PERMISSION_GRANTED) {
8944            throw new SecurityException("Requires permission "
8945                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8946        }
8947
8948        synchronized (this) {
8949            final long now = SystemClock.uptimeMillis();
8950            final long timeSinceLastIdle = now - mLastIdleTime;
8951            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8952            mLastIdleTime = now;
8953            mLowRamTimeSinceLastIdle = 0;
8954            if (mLowRamStartTime != 0) {
8955                mLowRamStartTime = now;
8956            }
8957
8958            StringBuilder sb = new StringBuilder(128);
8959            sb.append("Idle maintenance over ");
8960            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8961            sb.append(" low RAM for ");
8962            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8963            Slog.i(TAG, sb.toString());
8964
8965            // If at least 1/3 of our time since the last idle period has been spent
8966            // with RAM low, then we want to kill processes.
8967            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8968
8969            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8970                ProcessRecord proc = mLruProcesses.get(i);
8971                if (proc.notCachedSinceIdle) {
8972                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8973                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8974                        if (doKilling && proc.initialIdlePss != 0
8975                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8976                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8977                                    + " from " + proc.initialIdlePss + ")");
8978                        }
8979                    }
8980                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8981                    proc.notCachedSinceIdle = true;
8982                    proc.initialIdlePss = 0;
8983                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8984                            mSleeping, now);
8985                }
8986            }
8987
8988            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8989            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8990        }
8991    }
8992
8993    public final void startRunning(String pkg, String cls, String action,
8994            String data) {
8995        synchronized(this) {
8996            if (mStartRunning) {
8997                return;
8998            }
8999            mStartRunning = true;
9000            mTopComponent = pkg != null && cls != null
9001                    ? new ComponentName(pkg, cls) : null;
9002            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9003            mTopData = data;
9004            if (!mSystemReady) {
9005                return;
9006            }
9007        }
9008
9009        systemReady(null);
9010    }
9011
9012    private void retrieveSettings() {
9013        final ContentResolver resolver = mContext.getContentResolver();
9014        String debugApp = Settings.Global.getString(
9015            resolver, Settings.Global.DEBUG_APP);
9016        boolean waitForDebugger = Settings.Global.getInt(
9017            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9018        boolean alwaysFinishActivities = Settings.Global.getInt(
9019            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9020        boolean forceRtl = Settings.Global.getInt(
9021                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9022        // Transfer any global setting for forcing RTL layout, into a System Property
9023        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9024
9025        Configuration configuration = new Configuration();
9026        Settings.System.getConfiguration(resolver, configuration);
9027        if (forceRtl) {
9028            // This will take care of setting the correct layout direction flags
9029            configuration.setLayoutDirection(configuration.locale);
9030        }
9031
9032        synchronized (this) {
9033            mDebugApp = mOrigDebugApp = debugApp;
9034            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9035            mAlwaysFinishActivities = alwaysFinishActivities;
9036            // This happens before any activities are started, so we can
9037            // change mConfiguration in-place.
9038            updateConfigurationLocked(configuration, null, false, true);
9039            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9040        }
9041    }
9042
9043    public boolean testIsSystemReady() {
9044        // no need to synchronize(this) just to read & return the value
9045        return mSystemReady;
9046    }
9047
9048    private static File getCalledPreBootReceiversFile() {
9049        File dataDir = Environment.getDataDirectory();
9050        File systemDir = new File(dataDir, "system");
9051        File fname = new File(systemDir, "called_pre_boots.dat");
9052        return fname;
9053    }
9054
9055    static final int LAST_DONE_VERSION = 10000;
9056
9057    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9058        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9059        File file = getCalledPreBootReceiversFile();
9060        FileInputStream fis = null;
9061        try {
9062            fis = new FileInputStream(file);
9063            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9064            int fvers = dis.readInt();
9065            if (fvers == LAST_DONE_VERSION) {
9066                String vers = dis.readUTF();
9067                String codename = dis.readUTF();
9068                String build = dis.readUTF();
9069                if (android.os.Build.VERSION.RELEASE.equals(vers)
9070                        && android.os.Build.VERSION.CODENAME.equals(codename)
9071                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9072                    int num = dis.readInt();
9073                    while (num > 0) {
9074                        num--;
9075                        String pkg = dis.readUTF();
9076                        String cls = dis.readUTF();
9077                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9078                    }
9079                }
9080            }
9081        } catch (FileNotFoundException e) {
9082        } catch (IOException e) {
9083            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9084        } finally {
9085            if (fis != null) {
9086                try {
9087                    fis.close();
9088                } catch (IOException e) {
9089                }
9090            }
9091        }
9092        return lastDoneReceivers;
9093    }
9094
9095    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9096        File file = getCalledPreBootReceiversFile();
9097        FileOutputStream fos = null;
9098        DataOutputStream dos = null;
9099        try {
9100            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9101            fos = new FileOutputStream(file);
9102            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9103            dos.writeInt(LAST_DONE_VERSION);
9104            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9105            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9106            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9107            dos.writeInt(list.size());
9108            for (int i=0; i<list.size(); i++) {
9109                dos.writeUTF(list.get(i).getPackageName());
9110                dos.writeUTF(list.get(i).getClassName());
9111            }
9112        } catch (IOException e) {
9113            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9114            file.delete();
9115        } finally {
9116            FileUtils.sync(fos);
9117            if (dos != null) {
9118                try {
9119                    dos.close();
9120                } catch (IOException e) {
9121                    // TODO Auto-generated catch block
9122                    e.printStackTrace();
9123                }
9124            }
9125        }
9126    }
9127
9128    public void systemReady(final Runnable goingCallback) {
9129        synchronized(this) {
9130            if (mSystemReady) {
9131                if (goingCallback != null) goingCallback.run();
9132                return;
9133            }
9134
9135            // Check to see if there are any update receivers to run.
9136            if (!mDidUpdate) {
9137                if (mWaitingUpdate) {
9138                    return;
9139                }
9140                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9141                List<ResolveInfo> ris = null;
9142                try {
9143                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9144                            intent, null, 0, 0);
9145                } catch (RemoteException e) {
9146                }
9147                if (ris != null) {
9148                    for (int i=ris.size()-1; i>=0; i--) {
9149                        if ((ris.get(i).activityInfo.applicationInfo.flags
9150                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9151                            ris.remove(i);
9152                        }
9153                    }
9154                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9155
9156                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9157
9158                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
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                        if (lastDoneReceivers.contains(comp)) {
9163                            ris.remove(i);
9164                            i--;
9165                        }
9166                    }
9167
9168                    final int[] users = getUsersLocked();
9169                    for (int i=0; i<ris.size(); i++) {
9170                        ActivityInfo ai = ris.get(i).activityInfo;
9171                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9172                        doneReceivers.add(comp);
9173                        intent.setComponent(comp);
9174                        for (int j=0; j<users.length; j++) {
9175                            IIntentReceiver finisher = null;
9176                            if (i == ris.size()-1 && j == users.length-1) {
9177                                finisher = new IIntentReceiver.Stub() {
9178                                    public void performReceive(Intent intent, int resultCode,
9179                                            String data, Bundle extras, boolean ordered,
9180                                            boolean sticky, int sendingUser) {
9181                                        // The raw IIntentReceiver interface is called
9182                                        // with the AM lock held, so redispatch to
9183                                        // execute our code without the lock.
9184                                        mHandler.post(new Runnable() {
9185                                            public void run() {
9186                                                synchronized (ActivityManagerService.this) {
9187                                                    mDidUpdate = true;
9188                                                }
9189                                                writeLastDonePreBootReceivers(doneReceivers);
9190                                                showBootMessage(mContext.getText(
9191                                                        R.string.android_upgrading_complete),
9192                                                        false);
9193                                                systemReady(goingCallback);
9194                                            }
9195                                        });
9196                                    }
9197                                };
9198                            }
9199                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9200                                    + " for user " + users[j]);
9201                            broadcastIntentLocked(null, null, intent, null, finisher,
9202                                    0, null, null, null, AppOpsManager.OP_NONE,
9203                                    true, false, MY_PID, Process.SYSTEM_UID,
9204                                    users[j]);
9205                            if (finisher != null) {
9206                                mWaitingUpdate = true;
9207                            }
9208                        }
9209                    }
9210                }
9211                if (mWaitingUpdate) {
9212                    return;
9213                }
9214                mDidUpdate = true;
9215            }
9216
9217            mAppOpsService.systemReady();
9218            mSystemReady = true;
9219            if (!mStartRunning) {
9220                return;
9221            }
9222        }
9223
9224        ArrayList<ProcessRecord> procsToKill = null;
9225        synchronized(mPidsSelfLocked) {
9226            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9227                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9228                if (!isAllowedWhileBooting(proc.info)){
9229                    if (procsToKill == null) {
9230                        procsToKill = new ArrayList<ProcessRecord>();
9231                    }
9232                    procsToKill.add(proc);
9233                }
9234            }
9235        }
9236
9237        synchronized(this) {
9238            if (procsToKill != null) {
9239                for (int i=procsToKill.size()-1; i>=0; i--) {
9240                    ProcessRecord proc = procsToKill.get(i);
9241                    Slog.i(TAG, "Removing system update proc: " + proc);
9242                    removeProcessLocked(proc, true, false, "system update done");
9243                }
9244            }
9245
9246            // Now that we have cleaned up any update processes, we
9247            // are ready to start launching real processes and know that
9248            // we won't trample on them any more.
9249            mProcessesReady = true;
9250        }
9251
9252        Slog.i(TAG, "System now ready");
9253        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9254            SystemClock.uptimeMillis());
9255
9256        synchronized(this) {
9257            // Make sure we have no pre-ready processes sitting around.
9258
9259            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
9260                ResolveInfo ri = mContext.getPackageManager()
9261                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9262                                STOCK_PM_FLAGS);
9263                CharSequence errorMsg = null;
9264                if (ri != null) {
9265                    ActivityInfo ai = ri.activityInfo;
9266                    ApplicationInfo app = ai.applicationInfo;
9267                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9268                        mTopAction = Intent.ACTION_FACTORY_TEST;
9269                        mTopData = null;
9270                        mTopComponent = new ComponentName(app.packageName,
9271                                ai.name);
9272                    } else {
9273                        errorMsg = mContext.getResources().getText(
9274                                com.android.internal.R.string.factorytest_not_system);
9275                    }
9276                } else {
9277                    errorMsg = mContext.getResources().getText(
9278                            com.android.internal.R.string.factorytest_no_action);
9279                }
9280                if (errorMsg != null) {
9281                    mTopAction = null;
9282                    mTopData = null;
9283                    mTopComponent = null;
9284                    Message msg = Message.obtain();
9285                    msg.what = SHOW_FACTORY_ERROR_MSG;
9286                    msg.getData().putCharSequence("msg", errorMsg);
9287                    mHandler.sendMessage(msg);
9288                }
9289            }
9290        }
9291
9292        retrieveSettings();
9293
9294        synchronized (this) {
9295            readGrantedUriPermissionsLocked();
9296        }
9297
9298        if (goingCallback != null) goingCallback.run();
9299
9300        synchronized (this) {
9301            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
9302                try {
9303                    List apps = AppGlobals.getPackageManager().
9304                        getPersistentApplications(STOCK_PM_FLAGS);
9305                    if (apps != null) {
9306                        int N = apps.size();
9307                        int i;
9308                        for (i=0; i<N; i++) {
9309                            ApplicationInfo info
9310                                = (ApplicationInfo)apps.get(i);
9311                            if (info != null &&
9312                                    !info.packageName.equals("android")) {
9313                                addAppLocked(info, false);
9314                            }
9315                        }
9316                    }
9317                } catch (RemoteException ex) {
9318                    // pm is in same process, this will never happen.
9319                }
9320            }
9321
9322            // Start up initial activity.
9323            mBooting = true;
9324
9325            try {
9326                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9327                    Message msg = Message.obtain();
9328                    msg.what = SHOW_UID_ERROR_MSG;
9329                    mHandler.sendMessage(msg);
9330                }
9331            } catch (RemoteException e) {
9332            }
9333
9334            long ident = Binder.clearCallingIdentity();
9335            try {
9336                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9337                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9338                        | Intent.FLAG_RECEIVER_FOREGROUND);
9339                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9340                broadcastIntentLocked(null, null, intent,
9341                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9342                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9343                intent = new Intent(Intent.ACTION_USER_STARTING);
9344                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9345                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9346                broadcastIntentLocked(null, null, intent,
9347                        null, new IIntentReceiver.Stub() {
9348                            @Override
9349                            public void performReceive(Intent intent, int resultCode, String data,
9350                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9351                                    throws RemoteException {
9352                            }
9353                        }, 0, null, null,
9354                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9355                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9356            } finally {
9357                Binder.restoreCallingIdentity(ident);
9358            }
9359            mStackSupervisor.resumeTopActivitiesLocked();
9360            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9361        }
9362    }
9363
9364    private boolean makeAppCrashingLocked(ProcessRecord app,
9365            String shortMsg, String longMsg, String stackTrace) {
9366        app.crashing = true;
9367        app.crashingReport = generateProcessError(app,
9368                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9369        startAppProblemLocked(app);
9370        app.stopFreezingAllLocked();
9371        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9372    }
9373
9374    private void makeAppNotRespondingLocked(ProcessRecord app,
9375            String activity, String shortMsg, String longMsg) {
9376        app.notResponding = true;
9377        app.notRespondingReport = generateProcessError(app,
9378                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9379                activity, shortMsg, longMsg, null);
9380        startAppProblemLocked(app);
9381        app.stopFreezingAllLocked();
9382    }
9383
9384    /**
9385     * Generate a process error record, suitable for attachment to a ProcessRecord.
9386     *
9387     * @param app The ProcessRecord in which the error occurred.
9388     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9389     *                      ActivityManager.AppErrorStateInfo
9390     * @param activity The activity associated with the crash, if known.
9391     * @param shortMsg Short message describing the crash.
9392     * @param longMsg Long message describing the crash.
9393     * @param stackTrace Full crash stack trace, may be null.
9394     *
9395     * @return Returns a fully-formed AppErrorStateInfo record.
9396     */
9397    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9398            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9399        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9400
9401        report.condition = condition;
9402        report.processName = app.processName;
9403        report.pid = app.pid;
9404        report.uid = app.info.uid;
9405        report.tag = activity;
9406        report.shortMsg = shortMsg;
9407        report.longMsg = longMsg;
9408        report.stackTrace = stackTrace;
9409
9410        return report;
9411    }
9412
9413    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9414        synchronized (this) {
9415            app.crashing = false;
9416            app.crashingReport = null;
9417            app.notResponding = false;
9418            app.notRespondingReport = null;
9419            if (app.anrDialog == fromDialog) {
9420                app.anrDialog = null;
9421            }
9422            if (app.waitDialog == fromDialog) {
9423                app.waitDialog = null;
9424            }
9425            if (app.pid > 0 && app.pid != MY_PID) {
9426                handleAppCrashLocked(app, null, null, null);
9427                killUnneededProcessLocked(app, "user request after error");
9428            }
9429        }
9430    }
9431
9432    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9433            String stackTrace) {
9434        long now = SystemClock.uptimeMillis();
9435
9436        Long crashTime;
9437        if (!app.isolated) {
9438            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9439        } else {
9440            crashTime = null;
9441        }
9442        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9443            // This process loses!
9444            Slog.w(TAG, "Process " + app.info.processName
9445                    + " has crashed too many times: killing!");
9446            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9447                    app.userId, app.info.processName, app.uid);
9448            mStackSupervisor.handleAppCrashLocked(app);
9449            if (!app.persistent) {
9450                // We don't want to start this process again until the user
9451                // explicitly does so...  but for persistent process, we really
9452                // need to keep it running.  If a persistent process is actually
9453                // repeatedly crashing, then badness for everyone.
9454                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9455                        app.info.processName);
9456                if (!app.isolated) {
9457                    // XXX We don't have a way to mark isolated processes
9458                    // as bad, since they don't have a peristent identity.
9459                    mBadProcesses.put(app.info.processName, app.uid,
9460                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9461                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9462                }
9463                app.bad = true;
9464                app.removed = true;
9465                // Don't let services in this process be restarted and potentially
9466                // annoy the user repeatedly.  Unless it is persistent, since those
9467                // processes run critical code.
9468                removeProcessLocked(app, false, false, "crash");
9469                mStackSupervisor.resumeTopActivitiesLocked();
9470                return false;
9471            }
9472            mStackSupervisor.resumeTopActivitiesLocked();
9473        } else {
9474            mStackSupervisor.finishTopRunningActivityLocked(app);
9475        }
9476
9477        // Bump up the crash count of any services currently running in the proc.
9478        for (int i=app.services.size()-1; i>=0; i--) {
9479            // Any services running in the application need to be placed
9480            // back in the pending list.
9481            ServiceRecord sr = app.services.valueAt(i);
9482            sr.crashCount++;
9483        }
9484
9485        // If the crashing process is what we consider to be the "home process" and it has been
9486        // replaced by a third-party app, clear the package preferred activities from packages
9487        // with a home activity running in the process to prevent a repeatedly crashing app
9488        // from blocking the user to manually clear the list.
9489        final ArrayList<ActivityRecord> activities = app.activities;
9490        if (app == mHomeProcess && activities.size() > 0
9491                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9492            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9493                final ActivityRecord r = activities.get(activityNdx);
9494                if (r.isHomeActivity()) {
9495                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9496                    try {
9497                        ActivityThread.getPackageManager()
9498                                .clearPackagePreferredActivities(r.packageName);
9499                    } catch (RemoteException c) {
9500                        // pm is in same process, this will never happen.
9501                    }
9502                }
9503            }
9504        }
9505
9506        if (!app.isolated) {
9507            // XXX Can't keep track of crash times for isolated processes,
9508            // because they don't have a perisistent identity.
9509            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9510        }
9511
9512        return true;
9513    }
9514
9515    void startAppProblemLocked(ProcessRecord app) {
9516        if (app.userId == mCurrentUserId) {
9517            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9518                    mContext, app.info.packageName, app.info.flags);
9519        } else {
9520            // If this app is not running under the current user, then we
9521            // can't give it a report button because that would require
9522            // launching the report UI under a different user.
9523            app.errorReportReceiver = null;
9524        }
9525        skipCurrentReceiverLocked(app);
9526    }
9527
9528    void skipCurrentReceiverLocked(ProcessRecord app) {
9529        for (BroadcastQueue queue : mBroadcastQueues) {
9530            queue.skipCurrentReceiverLocked(app);
9531        }
9532    }
9533
9534    /**
9535     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9536     * The application process will exit immediately after this call returns.
9537     * @param app object of the crashing app, null for the system server
9538     * @param crashInfo describing the exception
9539     */
9540    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9541        ProcessRecord r = findAppProcess(app, "Crash");
9542        final String processName = app == null ? "system_server"
9543                : (r == null ? "unknown" : r.processName);
9544
9545        handleApplicationCrashInner("crash", r, processName, crashInfo);
9546    }
9547
9548    /* Native crash reporting uses this inner version because it needs to be somewhat
9549     * decoupled from the AM-managed cleanup lifecycle
9550     */
9551    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9552            ApplicationErrorReport.CrashInfo crashInfo) {
9553        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9554                UserHandle.getUserId(Binder.getCallingUid()), processName,
9555                r == null ? -1 : r.info.flags,
9556                crashInfo.exceptionClassName,
9557                crashInfo.exceptionMessage,
9558                crashInfo.throwFileName,
9559                crashInfo.throwLineNumber);
9560
9561        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9562
9563        crashApplication(r, crashInfo);
9564    }
9565
9566    public void handleApplicationStrictModeViolation(
9567            IBinder app,
9568            int violationMask,
9569            StrictMode.ViolationInfo info) {
9570        ProcessRecord r = findAppProcess(app, "StrictMode");
9571        if (r == null) {
9572            return;
9573        }
9574
9575        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9576            Integer stackFingerprint = info.hashCode();
9577            boolean logIt = true;
9578            synchronized (mAlreadyLoggedViolatedStacks) {
9579                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9580                    logIt = false;
9581                    // TODO: sub-sample into EventLog for these, with
9582                    // the info.durationMillis?  Then we'd get
9583                    // the relative pain numbers, without logging all
9584                    // the stack traces repeatedly.  We'd want to do
9585                    // likewise in the client code, which also does
9586                    // dup suppression, before the Binder call.
9587                } else {
9588                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9589                        mAlreadyLoggedViolatedStacks.clear();
9590                    }
9591                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9592                }
9593            }
9594            if (logIt) {
9595                logStrictModeViolationToDropBox(r, info);
9596            }
9597        }
9598
9599        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9600            AppErrorResult result = new AppErrorResult();
9601            synchronized (this) {
9602                final long origId = Binder.clearCallingIdentity();
9603
9604                Message msg = Message.obtain();
9605                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9606                HashMap<String, Object> data = new HashMap<String, Object>();
9607                data.put("result", result);
9608                data.put("app", r);
9609                data.put("violationMask", violationMask);
9610                data.put("info", info);
9611                msg.obj = data;
9612                mHandler.sendMessage(msg);
9613
9614                Binder.restoreCallingIdentity(origId);
9615            }
9616            int res = result.get();
9617            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9618        }
9619    }
9620
9621    // Depending on the policy in effect, there could be a bunch of
9622    // these in quick succession so we try to batch these together to
9623    // minimize disk writes, number of dropbox entries, and maximize
9624    // compression, by having more fewer, larger records.
9625    private void logStrictModeViolationToDropBox(
9626            ProcessRecord process,
9627            StrictMode.ViolationInfo info) {
9628        if (info == null) {
9629            return;
9630        }
9631        final boolean isSystemApp = process == null ||
9632                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9633                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9634        final String processName = process == null ? "unknown" : process.processName;
9635        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9636        final DropBoxManager dbox = (DropBoxManager)
9637                mContext.getSystemService(Context.DROPBOX_SERVICE);
9638
9639        // Exit early if the dropbox isn't configured to accept this report type.
9640        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9641
9642        boolean bufferWasEmpty;
9643        boolean needsFlush;
9644        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9645        synchronized (sb) {
9646            bufferWasEmpty = sb.length() == 0;
9647            appendDropBoxProcessHeaders(process, processName, sb);
9648            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9649            sb.append("System-App: ").append(isSystemApp).append("\n");
9650            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9651            if (info.violationNumThisLoop != 0) {
9652                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9653            }
9654            if (info.numAnimationsRunning != 0) {
9655                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9656            }
9657            if (info.broadcastIntentAction != null) {
9658                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9659            }
9660            if (info.durationMillis != -1) {
9661                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9662            }
9663            if (info.numInstances != -1) {
9664                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9665            }
9666            if (info.tags != null) {
9667                for (String tag : info.tags) {
9668                    sb.append("Span-Tag: ").append(tag).append("\n");
9669                }
9670            }
9671            sb.append("\n");
9672            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9673                sb.append(info.crashInfo.stackTrace);
9674            }
9675            sb.append("\n");
9676
9677            // Only buffer up to ~64k.  Various logging bits truncate
9678            // things at 128k.
9679            needsFlush = (sb.length() > 64 * 1024);
9680        }
9681
9682        // Flush immediately if the buffer's grown too large, or this
9683        // is a non-system app.  Non-system apps are isolated with a
9684        // different tag & policy and not batched.
9685        //
9686        // Batching is useful during internal testing with
9687        // StrictMode settings turned up high.  Without batching,
9688        // thousands of separate files could be created on boot.
9689        if (!isSystemApp || needsFlush) {
9690            new Thread("Error dump: " + dropboxTag) {
9691                @Override
9692                public void run() {
9693                    String report;
9694                    synchronized (sb) {
9695                        report = sb.toString();
9696                        sb.delete(0, sb.length());
9697                        sb.trimToSize();
9698                    }
9699                    if (report.length() != 0) {
9700                        dbox.addText(dropboxTag, report);
9701                    }
9702                }
9703            }.start();
9704            return;
9705        }
9706
9707        // System app batching:
9708        if (!bufferWasEmpty) {
9709            // An existing dropbox-writing thread is outstanding, so
9710            // we don't need to start it up.  The existing thread will
9711            // catch the buffer appends we just did.
9712            return;
9713        }
9714
9715        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9716        // (After this point, we shouldn't access AMS internal data structures.)
9717        new Thread("Error dump: " + dropboxTag) {
9718            @Override
9719            public void run() {
9720                // 5 second sleep to let stacks arrive and be batched together
9721                try {
9722                    Thread.sleep(5000);  // 5 seconds
9723                } catch (InterruptedException e) {}
9724
9725                String errorReport;
9726                synchronized (mStrictModeBuffer) {
9727                    errorReport = mStrictModeBuffer.toString();
9728                    if (errorReport.length() == 0) {
9729                        return;
9730                    }
9731                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9732                    mStrictModeBuffer.trimToSize();
9733                }
9734                dbox.addText(dropboxTag, errorReport);
9735            }
9736        }.start();
9737    }
9738
9739    /**
9740     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9741     * @param app object of the crashing app, null for the system server
9742     * @param tag reported by the caller
9743     * @param crashInfo describing the context of the error
9744     * @return true if the process should exit immediately (WTF is fatal)
9745     */
9746    public boolean handleApplicationWtf(IBinder app, String tag,
9747            ApplicationErrorReport.CrashInfo crashInfo) {
9748        ProcessRecord r = findAppProcess(app, "WTF");
9749        final String processName = app == null ? "system_server"
9750                : (r == null ? "unknown" : r.processName);
9751
9752        EventLog.writeEvent(EventLogTags.AM_WTF,
9753                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9754                processName,
9755                r == null ? -1 : r.info.flags,
9756                tag, crashInfo.exceptionMessage);
9757
9758        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9759
9760        if (r != null && r.pid != Process.myPid() &&
9761                Settings.Global.getInt(mContext.getContentResolver(),
9762                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9763            crashApplication(r, crashInfo);
9764            return true;
9765        } else {
9766            return false;
9767        }
9768    }
9769
9770    /**
9771     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9772     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9773     */
9774    private ProcessRecord findAppProcess(IBinder app, String reason) {
9775        if (app == null) {
9776            return null;
9777        }
9778
9779        synchronized (this) {
9780            final int NP = mProcessNames.getMap().size();
9781            for (int ip=0; ip<NP; ip++) {
9782                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9783                final int NA = apps.size();
9784                for (int ia=0; ia<NA; ia++) {
9785                    ProcessRecord p = apps.valueAt(ia);
9786                    if (p.thread != null && p.thread.asBinder() == app) {
9787                        return p;
9788                    }
9789                }
9790            }
9791
9792            Slog.w(TAG, "Can't find mystery application for " + reason
9793                    + " from pid=" + Binder.getCallingPid()
9794                    + " uid=" + Binder.getCallingUid() + ": " + app);
9795            return null;
9796        }
9797    }
9798
9799    /**
9800     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9801     * to append various headers to the dropbox log text.
9802     */
9803    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9804            StringBuilder sb) {
9805        // Watchdog thread ends up invoking this function (with
9806        // a null ProcessRecord) to add the stack file to dropbox.
9807        // Do not acquire a lock on this (am) in such cases, as it
9808        // could cause a potential deadlock, if and when watchdog
9809        // is invoked due to unavailability of lock on am and it
9810        // would prevent watchdog from killing system_server.
9811        if (process == null) {
9812            sb.append("Process: ").append(processName).append("\n");
9813            return;
9814        }
9815        // Note: ProcessRecord 'process' is guarded by the service
9816        // instance.  (notably process.pkgList, which could otherwise change
9817        // concurrently during execution of this method)
9818        synchronized (this) {
9819            sb.append("Process: ").append(processName).append("\n");
9820            int flags = process.info.flags;
9821            IPackageManager pm = AppGlobals.getPackageManager();
9822            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9823            for (int ip=0; ip<process.pkgList.size(); ip++) {
9824                String pkg = process.pkgList.keyAt(ip);
9825                sb.append("Package: ").append(pkg);
9826                try {
9827                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9828                    if (pi != null) {
9829                        sb.append(" v").append(pi.versionCode);
9830                        if (pi.versionName != null) {
9831                            sb.append(" (").append(pi.versionName).append(")");
9832                        }
9833                    }
9834                } catch (RemoteException e) {
9835                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9836                }
9837                sb.append("\n");
9838            }
9839        }
9840    }
9841
9842    private static String processClass(ProcessRecord process) {
9843        if (process == null || process.pid == MY_PID) {
9844            return "system_server";
9845        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9846            return "system_app";
9847        } else {
9848            return "data_app";
9849        }
9850    }
9851
9852    /**
9853     * Write a description of an error (crash, WTF, ANR) to the drop box.
9854     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9855     * @param process which caused the error, null means the system server
9856     * @param activity which triggered the error, null if unknown
9857     * @param parent activity related to the error, null if unknown
9858     * @param subject line related to the error, null if absent
9859     * @param report in long form describing the error, null if absent
9860     * @param logFile to include in the report, null if none
9861     * @param crashInfo giving an application stack trace, null if absent
9862     */
9863    public void addErrorToDropBox(String eventType,
9864            ProcessRecord process, String processName, ActivityRecord activity,
9865            ActivityRecord parent, String subject,
9866            final String report, final File logFile,
9867            final ApplicationErrorReport.CrashInfo crashInfo) {
9868        // NOTE -- this must never acquire the ActivityManagerService lock,
9869        // otherwise the watchdog may be prevented from resetting the system.
9870
9871        final String dropboxTag = processClass(process) + "_" + eventType;
9872        final DropBoxManager dbox = (DropBoxManager)
9873                mContext.getSystemService(Context.DROPBOX_SERVICE);
9874
9875        // Exit early if the dropbox isn't configured to accept this report type.
9876        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9877
9878        final StringBuilder sb = new StringBuilder(1024);
9879        appendDropBoxProcessHeaders(process, processName, sb);
9880        if (activity != null) {
9881            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9882        }
9883        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9884            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9885        }
9886        if (parent != null && parent != activity) {
9887            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9888        }
9889        if (subject != null) {
9890            sb.append("Subject: ").append(subject).append("\n");
9891        }
9892        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9893        if (Debug.isDebuggerConnected()) {
9894            sb.append("Debugger: Connected\n");
9895        }
9896        sb.append("\n");
9897
9898        // Do the rest in a worker thread to avoid blocking the caller on I/O
9899        // (After this point, we shouldn't access AMS internal data structures.)
9900        Thread worker = new Thread("Error dump: " + dropboxTag) {
9901            @Override
9902            public void run() {
9903                if (report != null) {
9904                    sb.append(report);
9905                }
9906                if (logFile != null) {
9907                    try {
9908                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9909                                    "\n\n[[TRUNCATED]]"));
9910                    } catch (IOException e) {
9911                        Slog.e(TAG, "Error reading " + logFile, e);
9912                    }
9913                }
9914                if (crashInfo != null && crashInfo.stackTrace != null) {
9915                    sb.append(crashInfo.stackTrace);
9916                }
9917
9918                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9919                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9920                if (lines > 0) {
9921                    sb.append("\n");
9922
9923                    // Merge several logcat streams, and take the last N lines
9924                    InputStreamReader input = null;
9925                    try {
9926                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9927                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9928                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9929
9930                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9931                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9932                        input = new InputStreamReader(logcat.getInputStream());
9933
9934                        int num;
9935                        char[] buf = new char[8192];
9936                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9937                    } catch (IOException e) {
9938                        Slog.e(TAG, "Error running logcat", e);
9939                    } finally {
9940                        if (input != null) try { input.close(); } catch (IOException e) {}
9941                    }
9942                }
9943
9944                dbox.addText(dropboxTag, sb.toString());
9945            }
9946        };
9947
9948        if (process == null) {
9949            // If process is null, we are being called from some internal code
9950            // and may be about to die -- run this synchronously.
9951            worker.run();
9952        } else {
9953            worker.start();
9954        }
9955    }
9956
9957    /**
9958     * Bring up the "unexpected error" dialog box for a crashing app.
9959     * Deal with edge cases (intercepts from instrumented applications,
9960     * ActivityController, error intent receivers, that sort of thing).
9961     * @param r the application crashing
9962     * @param crashInfo describing the failure
9963     */
9964    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9965        long timeMillis = System.currentTimeMillis();
9966        String shortMsg = crashInfo.exceptionClassName;
9967        String longMsg = crashInfo.exceptionMessage;
9968        String stackTrace = crashInfo.stackTrace;
9969        if (shortMsg != null && longMsg != null) {
9970            longMsg = shortMsg + ": " + longMsg;
9971        } else if (shortMsg != null) {
9972            longMsg = shortMsg;
9973        }
9974
9975        AppErrorResult result = new AppErrorResult();
9976        synchronized (this) {
9977            if (mController != null) {
9978                try {
9979                    String name = r != null ? r.processName : null;
9980                    int pid = r != null ? r.pid : Binder.getCallingPid();
9981                    if (!mController.appCrashed(name, pid,
9982                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9983                        Slog.w(TAG, "Force-killing crashed app " + name
9984                                + " at watcher's request");
9985                        Process.killProcess(pid);
9986                        return;
9987                    }
9988                } catch (RemoteException e) {
9989                    mController = null;
9990                    Watchdog.getInstance().setActivityController(null);
9991                }
9992            }
9993
9994            final long origId = Binder.clearCallingIdentity();
9995
9996            // If this process is running instrumentation, finish it.
9997            if (r != null && r.instrumentationClass != null) {
9998                Slog.w(TAG, "Error in app " + r.processName
9999                      + " running instrumentation " + r.instrumentationClass + ":");
10000                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10001                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10002                Bundle info = new Bundle();
10003                info.putString("shortMsg", shortMsg);
10004                info.putString("longMsg", longMsg);
10005                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10006                Binder.restoreCallingIdentity(origId);
10007                return;
10008            }
10009
10010            // If we can't identify the process or it's already exceeded its crash quota,
10011            // quit right away without showing a crash dialog.
10012            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10013                Binder.restoreCallingIdentity(origId);
10014                return;
10015            }
10016
10017            Message msg = Message.obtain();
10018            msg.what = SHOW_ERROR_MSG;
10019            HashMap data = new HashMap();
10020            data.put("result", result);
10021            data.put("app", r);
10022            msg.obj = data;
10023            mHandler.sendMessage(msg);
10024
10025            Binder.restoreCallingIdentity(origId);
10026        }
10027
10028        int res = result.get();
10029
10030        Intent appErrorIntent = null;
10031        synchronized (this) {
10032            if (r != null && !r.isolated) {
10033                // XXX Can't keep track of crash time for isolated processes,
10034                // since they don't have a persistent identity.
10035                mProcessCrashTimes.put(r.info.processName, r.uid,
10036                        SystemClock.uptimeMillis());
10037            }
10038            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10039                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10040            }
10041        }
10042
10043        if (appErrorIntent != null) {
10044            try {
10045                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10046            } catch (ActivityNotFoundException e) {
10047                Slog.w(TAG, "bug report receiver dissappeared", e);
10048            }
10049        }
10050    }
10051
10052    Intent createAppErrorIntentLocked(ProcessRecord r,
10053            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10054        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10055        if (report == null) {
10056            return null;
10057        }
10058        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10059        result.setComponent(r.errorReportReceiver);
10060        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10061        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10062        return result;
10063    }
10064
10065    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10066            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10067        if (r.errorReportReceiver == null) {
10068            return null;
10069        }
10070
10071        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10072            return null;
10073        }
10074
10075        ApplicationErrorReport report = new ApplicationErrorReport();
10076        report.packageName = r.info.packageName;
10077        report.installerPackageName = r.errorReportReceiver.getPackageName();
10078        report.processName = r.processName;
10079        report.time = timeMillis;
10080        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10081
10082        if (r.crashing || r.forceCrashReport) {
10083            report.type = ApplicationErrorReport.TYPE_CRASH;
10084            report.crashInfo = crashInfo;
10085        } else if (r.notResponding) {
10086            report.type = ApplicationErrorReport.TYPE_ANR;
10087            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10088
10089            report.anrInfo.activity = r.notRespondingReport.tag;
10090            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10091            report.anrInfo.info = r.notRespondingReport.longMsg;
10092        }
10093
10094        return report;
10095    }
10096
10097    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10098        enforceNotIsolatedCaller("getProcessesInErrorState");
10099        // assume our apps are happy - lazy create the list
10100        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10101
10102        final boolean allUsers = ActivityManager.checkUidPermission(
10103                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10104                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10105        int userId = UserHandle.getUserId(Binder.getCallingUid());
10106
10107        synchronized (this) {
10108
10109            // iterate across all processes
10110            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10111                ProcessRecord app = mLruProcesses.get(i);
10112                if (!allUsers && app.userId != userId) {
10113                    continue;
10114                }
10115                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10116                    // This one's in trouble, so we'll generate a report for it
10117                    // crashes are higher priority (in case there's a crash *and* an anr)
10118                    ActivityManager.ProcessErrorStateInfo report = null;
10119                    if (app.crashing) {
10120                        report = app.crashingReport;
10121                    } else if (app.notResponding) {
10122                        report = app.notRespondingReport;
10123                    }
10124
10125                    if (report != null) {
10126                        if (errList == null) {
10127                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10128                        }
10129                        errList.add(report);
10130                    } else {
10131                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10132                                " crashing = " + app.crashing +
10133                                " notResponding = " + app.notResponding);
10134                    }
10135                }
10136            }
10137        }
10138
10139        return errList;
10140    }
10141
10142    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10143        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10144            if (currApp != null) {
10145                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10146            }
10147            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10148        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10149            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10150        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10151            if (currApp != null) {
10152                currApp.lru = 0;
10153            }
10154            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10155        } else if (adj >= ProcessList.SERVICE_ADJ) {
10156            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10157        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10158            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10159        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10160            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10161        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10162            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10163        } else {
10164            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10165        }
10166    }
10167
10168    private void fillInProcMemInfo(ProcessRecord app,
10169            ActivityManager.RunningAppProcessInfo outInfo) {
10170        outInfo.pid = app.pid;
10171        outInfo.uid = app.info.uid;
10172        if (mHeavyWeightProcess == app) {
10173            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10174        }
10175        if (app.persistent) {
10176            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10177        }
10178        if (app.activities.size() > 0) {
10179            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10180        }
10181        outInfo.lastTrimLevel = app.trimMemoryLevel;
10182        int adj = app.curAdj;
10183        outInfo.importance = oomAdjToImportance(adj, outInfo);
10184        outInfo.importanceReasonCode = app.adjTypeCode;
10185    }
10186
10187    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10188        enforceNotIsolatedCaller("getRunningAppProcesses");
10189        // Lazy instantiation of list
10190        List<ActivityManager.RunningAppProcessInfo> runList = null;
10191        final boolean allUsers = ActivityManager.checkUidPermission(
10192                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10193                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10194        int userId = UserHandle.getUserId(Binder.getCallingUid());
10195        synchronized (this) {
10196            // Iterate across all processes
10197            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10198                ProcessRecord app = mLruProcesses.get(i);
10199                if (!allUsers && app.userId != userId) {
10200                    continue;
10201                }
10202                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10203                    // Generate process state info for running application
10204                    ActivityManager.RunningAppProcessInfo currApp =
10205                        new ActivityManager.RunningAppProcessInfo(app.processName,
10206                                app.pid, app.getPackageList());
10207                    fillInProcMemInfo(app, currApp);
10208                    if (app.adjSource instanceof ProcessRecord) {
10209                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10210                        currApp.importanceReasonImportance = oomAdjToImportance(
10211                                app.adjSourceOom, null);
10212                    } else if (app.adjSource instanceof ActivityRecord) {
10213                        ActivityRecord r = (ActivityRecord)app.adjSource;
10214                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10215                    }
10216                    if (app.adjTarget instanceof ComponentName) {
10217                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10218                    }
10219                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10220                    //        + " lru=" + currApp.lru);
10221                    if (runList == null) {
10222                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10223                    }
10224                    runList.add(currApp);
10225                }
10226            }
10227        }
10228        return runList;
10229    }
10230
10231    public List<ApplicationInfo> getRunningExternalApplications() {
10232        enforceNotIsolatedCaller("getRunningExternalApplications");
10233        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10234        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10235        if (runningApps != null && runningApps.size() > 0) {
10236            Set<String> extList = new HashSet<String>();
10237            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10238                if (app.pkgList != null) {
10239                    for (String pkg : app.pkgList) {
10240                        extList.add(pkg);
10241                    }
10242                }
10243            }
10244            IPackageManager pm = AppGlobals.getPackageManager();
10245            for (String pkg : extList) {
10246                try {
10247                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10248                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10249                        retList.add(info);
10250                    }
10251                } catch (RemoteException e) {
10252                }
10253            }
10254        }
10255        return retList;
10256    }
10257
10258    @Override
10259    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10260        enforceNotIsolatedCaller("getMyMemoryState");
10261        synchronized (this) {
10262            ProcessRecord proc;
10263            synchronized (mPidsSelfLocked) {
10264                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10265            }
10266            fillInProcMemInfo(proc, outInfo);
10267        }
10268    }
10269
10270    @Override
10271    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10272        if (checkCallingPermission(android.Manifest.permission.DUMP)
10273                != PackageManager.PERMISSION_GRANTED) {
10274            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10275                    + Binder.getCallingPid()
10276                    + ", uid=" + Binder.getCallingUid()
10277                    + " without permission "
10278                    + android.Manifest.permission.DUMP);
10279            return;
10280        }
10281
10282        boolean dumpAll = false;
10283        boolean dumpClient = false;
10284        String dumpPackage = null;
10285
10286        int opti = 0;
10287        while (opti < args.length) {
10288            String opt = args[opti];
10289            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10290                break;
10291            }
10292            opti++;
10293            if ("-a".equals(opt)) {
10294                dumpAll = true;
10295            } else if ("-c".equals(opt)) {
10296                dumpClient = true;
10297            } else if ("-h".equals(opt)) {
10298                pw.println("Activity manager dump options:");
10299                pw.println("  [-a] [-c] [-h] [cmd] ...");
10300                pw.println("  cmd may be one of:");
10301                pw.println("    a[ctivities]: activity stack state");
10302                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10303                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10304                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10305                pw.println("    o[om]: out of memory management");
10306                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10307                pw.println("    provider [COMP_SPEC]: provider client-side state");
10308                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10309                pw.println("    service [COMP_SPEC]: service client-side state");
10310                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10311                pw.println("    all: dump all activities");
10312                pw.println("    top: dump the top activity");
10313                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10314                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10315                pw.println("    a partial substring in a component name, a");
10316                pw.println("    hex object identifier.");
10317                pw.println("  -a: include all available server state.");
10318                pw.println("  -c: include client state.");
10319                return;
10320            } else {
10321                pw.println("Unknown argument: " + opt + "; use -h for help");
10322            }
10323        }
10324
10325        long origId = Binder.clearCallingIdentity();
10326        boolean more = false;
10327        // Is the caller requesting to dump a particular piece of data?
10328        if (opti < args.length) {
10329            String cmd = args[opti];
10330            opti++;
10331            if ("activities".equals(cmd) || "a".equals(cmd)) {
10332                synchronized (this) {
10333                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10334                }
10335            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10336                String[] newArgs;
10337                String name;
10338                if (opti >= args.length) {
10339                    name = null;
10340                    newArgs = EMPTY_STRING_ARRAY;
10341                } else {
10342                    name = args[opti];
10343                    opti++;
10344                    newArgs = new String[args.length - opti];
10345                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10346                            args.length - opti);
10347                }
10348                synchronized (this) {
10349                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10350                }
10351            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10352                String[] newArgs;
10353                String name;
10354                if (opti >= args.length) {
10355                    name = null;
10356                    newArgs = EMPTY_STRING_ARRAY;
10357                } else {
10358                    name = args[opti];
10359                    opti++;
10360                    newArgs = new String[args.length - opti];
10361                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10362                            args.length - opti);
10363                }
10364                synchronized (this) {
10365                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10366                }
10367            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10368                String[] newArgs;
10369                String name;
10370                if (opti >= args.length) {
10371                    name = null;
10372                    newArgs = EMPTY_STRING_ARRAY;
10373                } else {
10374                    name = args[opti];
10375                    opti++;
10376                    newArgs = new String[args.length - opti];
10377                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10378                            args.length - opti);
10379                }
10380                synchronized (this) {
10381                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10382                }
10383            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10384                synchronized (this) {
10385                    dumpOomLocked(fd, pw, args, opti, true);
10386                }
10387            } else if ("provider".equals(cmd)) {
10388                String[] newArgs;
10389                String name;
10390                if (opti >= args.length) {
10391                    name = null;
10392                    newArgs = EMPTY_STRING_ARRAY;
10393                } else {
10394                    name = args[opti];
10395                    opti++;
10396                    newArgs = new String[args.length - opti];
10397                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10398                }
10399                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10400                    pw.println("No providers match: " + name);
10401                    pw.println("Use -h for help.");
10402                }
10403            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10404                synchronized (this) {
10405                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10406                }
10407            } else if ("service".equals(cmd)) {
10408                String[] newArgs;
10409                String name;
10410                if (opti >= args.length) {
10411                    name = null;
10412                    newArgs = EMPTY_STRING_ARRAY;
10413                } else {
10414                    name = args[opti];
10415                    opti++;
10416                    newArgs = new String[args.length - opti];
10417                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10418                            args.length - opti);
10419                }
10420                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10421                    pw.println("No services match: " + name);
10422                    pw.println("Use -h for help.");
10423                }
10424            } else if ("package".equals(cmd)) {
10425                String[] newArgs;
10426                if (opti >= args.length) {
10427                    pw.println("package: no package name specified");
10428                    pw.println("Use -h for help.");
10429                } else {
10430                    dumpPackage = args[opti];
10431                    opti++;
10432                    newArgs = new String[args.length - opti];
10433                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10434                            args.length - opti);
10435                    args = newArgs;
10436                    opti = 0;
10437                    more = true;
10438                }
10439            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10440                synchronized (this) {
10441                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10442                }
10443            } else {
10444                // Dumping a single activity?
10445                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10446                    pw.println("Bad activity command, or no activities match: " + cmd);
10447                    pw.println("Use -h for help.");
10448                }
10449            }
10450            if (!more) {
10451                Binder.restoreCallingIdentity(origId);
10452                return;
10453            }
10454        }
10455
10456        // No piece of data specified, dump everything.
10457        synchronized (this) {
10458            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10459            pw.println();
10460            if (dumpAll) {
10461                pw.println("-------------------------------------------------------------------------------");
10462            }
10463            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10464            pw.println();
10465            if (dumpAll) {
10466                pw.println("-------------------------------------------------------------------------------");
10467            }
10468            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10469            pw.println();
10470            if (dumpAll) {
10471                pw.println("-------------------------------------------------------------------------------");
10472            }
10473            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10474            pw.println();
10475            if (dumpAll) {
10476                pw.println("-------------------------------------------------------------------------------");
10477            }
10478            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10479            pw.println();
10480            if (dumpAll) {
10481                pw.println("-------------------------------------------------------------------------------");
10482            }
10483            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10484        }
10485        Binder.restoreCallingIdentity(origId);
10486    }
10487
10488    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10489            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10490        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10491
10492        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10493                dumpPackage);
10494        boolean needSep = printedAnything;
10495
10496        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10497                dumpPackage, needSep, "  mFocusedActivity: ");
10498        if (printed) {
10499            printedAnything = true;
10500            needSep = false;
10501        }
10502
10503        if (dumpPackage == null) {
10504            if (needSep) {
10505                pw.println();
10506            }
10507            needSep = true;
10508            printedAnything = true;
10509            mStackSupervisor.dump(pw, "  ");
10510        }
10511
10512        if (mRecentTasks.size() > 0) {
10513            boolean printedHeader = false;
10514
10515            final int N = mRecentTasks.size();
10516            for (int i=0; i<N; i++) {
10517                TaskRecord tr = mRecentTasks.get(i);
10518                if (dumpPackage != null) {
10519                    if (tr.realActivity == null ||
10520                            !dumpPackage.equals(tr.realActivity)) {
10521                        continue;
10522                    }
10523                }
10524                if (!printedHeader) {
10525                    if (needSep) {
10526                        pw.println();
10527                    }
10528                    pw.println("  Recent tasks:");
10529                    printedHeader = true;
10530                    printedAnything = true;
10531                }
10532                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10533                        pw.println(tr);
10534                if (dumpAll) {
10535                    mRecentTasks.get(i).dump(pw, "    ");
10536                }
10537            }
10538        }
10539
10540        if (!printedAnything) {
10541            pw.println("  (nothing)");
10542        }
10543    }
10544
10545    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10546            int opti, boolean dumpAll, String dumpPackage) {
10547        boolean needSep = false;
10548        boolean printedAnything = false;
10549        int numPers = 0;
10550
10551        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10552
10553        if (dumpAll) {
10554            final int NP = mProcessNames.getMap().size();
10555            for (int ip=0; ip<NP; ip++) {
10556                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10557                final int NA = procs.size();
10558                for (int ia=0; ia<NA; ia++) {
10559                    ProcessRecord r = procs.valueAt(ia);
10560                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10561                        continue;
10562                    }
10563                    if (!needSep) {
10564                        pw.println("  All known processes:");
10565                        needSep = true;
10566                        printedAnything = true;
10567                    }
10568                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10569                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10570                        pw.print(" "); pw.println(r);
10571                    r.dump(pw, "    ");
10572                    if (r.persistent) {
10573                        numPers++;
10574                    }
10575                }
10576            }
10577        }
10578
10579        if (mIsolatedProcesses.size() > 0) {
10580            boolean printed = false;
10581            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10582                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10583                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10584                    continue;
10585                }
10586                if (!printed) {
10587                    if (needSep) {
10588                        pw.println();
10589                    }
10590                    pw.println("  Isolated process list (sorted by uid):");
10591                    printedAnything = true;
10592                    printed = true;
10593                    needSep = true;
10594                }
10595                pw.println(String.format("%sIsolated #%2d: %s",
10596                        "    ", i, r.toString()));
10597            }
10598        }
10599
10600        if (mLruProcesses.size() > 0) {
10601            if (needSep) {
10602                pw.println();
10603            }
10604            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10605                    pw.print(" total, non-act at ");
10606                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10607                    pw.print(", non-svc at ");
10608                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10609                    pw.println("):");
10610            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10611            needSep = true;
10612            printedAnything = true;
10613        }
10614
10615        if (dumpAll || dumpPackage != null) {
10616            synchronized (mPidsSelfLocked) {
10617                boolean printed = false;
10618                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10619                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10620                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10621                        continue;
10622                    }
10623                    if (!printed) {
10624                        if (needSep) pw.println();
10625                        needSep = true;
10626                        pw.println("  PID mappings:");
10627                        printed = true;
10628                        printedAnything = true;
10629                    }
10630                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10631                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10632                }
10633            }
10634        }
10635
10636        if (mForegroundProcesses.size() > 0) {
10637            synchronized (mPidsSelfLocked) {
10638                boolean printed = false;
10639                for (int i=0; i<mForegroundProcesses.size(); i++) {
10640                    ProcessRecord r = mPidsSelfLocked.get(
10641                            mForegroundProcesses.valueAt(i).pid);
10642                    if (dumpPackage != null && (r == null
10643                            || !r.pkgList.containsKey(dumpPackage))) {
10644                        continue;
10645                    }
10646                    if (!printed) {
10647                        if (needSep) pw.println();
10648                        needSep = true;
10649                        pw.println("  Foreground Processes:");
10650                        printed = true;
10651                        printedAnything = true;
10652                    }
10653                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10654                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10655                }
10656            }
10657        }
10658
10659        if (mPersistentStartingProcesses.size() > 0) {
10660            if (needSep) pw.println();
10661            needSep = true;
10662            printedAnything = true;
10663            pw.println("  Persisent processes that are starting:");
10664            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10665                    "Starting Norm", "Restarting PERS", dumpPackage);
10666        }
10667
10668        if (mRemovedProcesses.size() > 0) {
10669            if (needSep) pw.println();
10670            needSep = true;
10671            printedAnything = true;
10672            pw.println("  Processes that are being removed:");
10673            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10674                    "Removed Norm", "Removed PERS", dumpPackage);
10675        }
10676
10677        if (mProcessesOnHold.size() > 0) {
10678            if (needSep) pw.println();
10679            needSep = true;
10680            printedAnything = true;
10681            pw.println("  Processes that are on old until the system is ready:");
10682            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10683                    "OnHold Norm", "OnHold PERS", dumpPackage);
10684        }
10685
10686        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10687
10688        if (mProcessCrashTimes.getMap().size() > 0) {
10689            boolean printed = false;
10690            long now = SystemClock.uptimeMillis();
10691            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10692            final int NP = pmap.size();
10693            for (int ip=0; ip<NP; ip++) {
10694                String pname = pmap.keyAt(ip);
10695                SparseArray<Long> uids = pmap.valueAt(ip);
10696                final int N = uids.size();
10697                for (int i=0; i<N; i++) {
10698                    int puid = uids.keyAt(i);
10699                    ProcessRecord r = mProcessNames.get(pname, puid);
10700                    if (dumpPackage != null && (r == null
10701                            || !r.pkgList.containsKey(dumpPackage))) {
10702                        continue;
10703                    }
10704                    if (!printed) {
10705                        if (needSep) pw.println();
10706                        needSep = true;
10707                        pw.println("  Time since processes crashed:");
10708                        printed = true;
10709                        printedAnything = true;
10710                    }
10711                    pw.print("    Process "); pw.print(pname);
10712                            pw.print(" uid "); pw.print(puid);
10713                            pw.print(": last crashed ");
10714                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10715                            pw.println(" ago");
10716                }
10717            }
10718        }
10719
10720        if (mBadProcesses.getMap().size() > 0) {
10721            boolean printed = false;
10722            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10723            final int NP = pmap.size();
10724            for (int ip=0; ip<NP; ip++) {
10725                String pname = pmap.keyAt(ip);
10726                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10727                final int N = uids.size();
10728                for (int i=0; i<N; i++) {
10729                    int puid = uids.keyAt(i);
10730                    ProcessRecord r = mProcessNames.get(pname, puid);
10731                    if (dumpPackage != null && (r == null
10732                            || !r.pkgList.containsKey(dumpPackage))) {
10733                        continue;
10734                    }
10735                    if (!printed) {
10736                        if (needSep) pw.println();
10737                        needSep = true;
10738                        pw.println("  Bad processes:");
10739                        printedAnything = true;
10740                    }
10741                    BadProcessInfo info = uids.valueAt(i);
10742                    pw.print("    Bad process "); pw.print(pname);
10743                            pw.print(" uid "); pw.print(puid);
10744                            pw.print(": crashed at time "); pw.println(info.time);
10745                    if (info.shortMsg != null) {
10746                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10747                    }
10748                    if (info.longMsg != null) {
10749                        pw.print("      Long msg: "); pw.println(info.longMsg);
10750                    }
10751                    if (info.stack != null) {
10752                        pw.println("      Stack:");
10753                        int lastPos = 0;
10754                        for (int pos=0; pos<info.stack.length(); pos++) {
10755                            if (info.stack.charAt(pos) == '\n') {
10756                                pw.print("        ");
10757                                pw.write(info.stack, lastPos, pos-lastPos);
10758                                pw.println();
10759                                lastPos = pos+1;
10760                            }
10761                        }
10762                        if (lastPos < info.stack.length()) {
10763                            pw.print("        ");
10764                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10765                            pw.println();
10766                        }
10767                    }
10768                }
10769            }
10770        }
10771
10772        if (dumpPackage == null) {
10773            pw.println();
10774            needSep = false;
10775            pw.println("  mStartedUsers:");
10776            for (int i=0; i<mStartedUsers.size(); i++) {
10777                UserStartedState uss = mStartedUsers.valueAt(i);
10778                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10779                        pw.print(": "); uss.dump("", pw);
10780            }
10781            pw.print("  mStartedUserArray: [");
10782            for (int i=0; i<mStartedUserArray.length; i++) {
10783                if (i > 0) pw.print(", ");
10784                pw.print(mStartedUserArray[i]);
10785            }
10786            pw.println("]");
10787            pw.print("  mUserLru: [");
10788            for (int i=0; i<mUserLru.size(); i++) {
10789                if (i > 0) pw.print(", ");
10790                pw.print(mUserLru.get(i));
10791            }
10792            pw.println("]");
10793            if (dumpAll) {
10794                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10795            }
10796        }
10797        if (mHomeProcess != null && (dumpPackage == null
10798                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10799            if (needSep) {
10800                pw.println();
10801                needSep = false;
10802            }
10803            pw.println("  mHomeProcess: " + mHomeProcess);
10804        }
10805        if (mPreviousProcess != null && (dumpPackage == null
10806                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10807            if (needSep) {
10808                pw.println();
10809                needSep = false;
10810            }
10811            pw.println("  mPreviousProcess: " + mPreviousProcess);
10812        }
10813        if (dumpAll) {
10814            StringBuilder sb = new StringBuilder(128);
10815            sb.append("  mPreviousProcessVisibleTime: ");
10816            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10817            pw.println(sb);
10818        }
10819        if (mHeavyWeightProcess != null && (dumpPackage == null
10820                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10821            if (needSep) {
10822                pw.println();
10823                needSep = false;
10824            }
10825            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10826        }
10827        if (dumpPackage == null) {
10828            pw.println("  mConfiguration: " + mConfiguration);
10829        }
10830        if (dumpAll) {
10831            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10832            if (mCompatModePackages.getPackages().size() > 0) {
10833                boolean printed = false;
10834                for (Map.Entry<String, Integer> entry
10835                        : mCompatModePackages.getPackages().entrySet()) {
10836                    String pkg = entry.getKey();
10837                    int mode = entry.getValue();
10838                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10839                        continue;
10840                    }
10841                    if (!printed) {
10842                        pw.println("  mScreenCompatPackages:");
10843                        printed = true;
10844                    }
10845                    pw.print("    "); pw.print(pkg); pw.print(": ");
10846                            pw.print(mode); pw.println();
10847                }
10848            }
10849        }
10850        if (dumpPackage == null) {
10851            if (mSleeping || mWentToSleep || mLockScreenShown) {
10852                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10853                        + " mLockScreenShown " + mLockScreenShown);
10854            }
10855            if (mShuttingDown) {
10856                pw.println("  mShuttingDown=" + mShuttingDown);
10857            }
10858        }
10859        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10860                || mOrigWaitForDebugger) {
10861            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10862                    || dumpPackage.equals(mOrigDebugApp)) {
10863                if (needSep) {
10864                    pw.println();
10865                    needSep = false;
10866                }
10867                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10868                        + " mDebugTransient=" + mDebugTransient
10869                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10870            }
10871        }
10872        if (mOpenGlTraceApp != null) {
10873            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10874                if (needSep) {
10875                    pw.println();
10876                    needSep = false;
10877                }
10878                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10879            }
10880        }
10881        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10882                || mProfileFd != null) {
10883            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10884                if (needSep) {
10885                    pw.println();
10886                    needSep = false;
10887                }
10888                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10889                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10890                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10891                        + mAutoStopProfiler);
10892            }
10893        }
10894        if (dumpPackage == null) {
10895            if (mAlwaysFinishActivities || mController != null) {
10896                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10897                        + " mController=" + mController);
10898            }
10899            if (dumpAll) {
10900                pw.println("  Total persistent processes: " + numPers);
10901                pw.println("  mStartRunning=" + mStartRunning
10902                        + " mProcessesReady=" + mProcessesReady
10903                        + " mSystemReady=" + mSystemReady);
10904                pw.println("  mBooting=" + mBooting
10905                        + " mBooted=" + mBooted
10906                        + " mFactoryTest=" + mFactoryTest);
10907                pw.print("  mLastPowerCheckRealtime=");
10908                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10909                        pw.println("");
10910                pw.print("  mLastPowerCheckUptime=");
10911                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10912                        pw.println("");
10913                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10914                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10915                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10916                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10917                        + " (" + mLruProcesses.size() + " total)"
10918                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10919                        + " mNumServiceProcs=" + mNumServiceProcs
10920                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10921                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10922                        + " mLastMemoryLevel" + mLastMemoryLevel
10923                        + " mLastNumProcesses" + mLastNumProcesses);
10924                long now = SystemClock.uptimeMillis();
10925                pw.print("  mLastIdleTime=");
10926                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10927                        pw.print(" mLowRamSinceLastIdle=");
10928                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10929                        pw.println();
10930            }
10931        }
10932
10933        if (!printedAnything) {
10934            pw.println("  (nothing)");
10935        }
10936    }
10937
10938    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10939            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10940        if (mProcessesToGc.size() > 0) {
10941            boolean printed = false;
10942            long now = SystemClock.uptimeMillis();
10943            for (int i=0; i<mProcessesToGc.size(); i++) {
10944                ProcessRecord proc = mProcessesToGc.get(i);
10945                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10946                    continue;
10947                }
10948                if (!printed) {
10949                    if (needSep) pw.println();
10950                    needSep = true;
10951                    pw.println("  Processes that are waiting to GC:");
10952                    printed = true;
10953                }
10954                pw.print("    Process "); pw.println(proc);
10955                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10956                        pw.print(", last gced=");
10957                        pw.print(now-proc.lastRequestedGc);
10958                        pw.print(" ms ago, last lowMem=");
10959                        pw.print(now-proc.lastLowMemory);
10960                        pw.println(" ms ago");
10961
10962            }
10963        }
10964        return needSep;
10965    }
10966
10967    void printOomLevel(PrintWriter pw, String name, int adj) {
10968        pw.print("    ");
10969        if (adj >= 0) {
10970            pw.print(' ');
10971            if (adj < 10) pw.print(' ');
10972        } else {
10973            if (adj > -10) pw.print(' ');
10974        }
10975        pw.print(adj);
10976        pw.print(": ");
10977        pw.print(name);
10978        pw.print(" (");
10979        pw.print(mProcessList.getMemLevel(adj)/1024);
10980        pw.println(" kB)");
10981    }
10982
10983    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10984            int opti, boolean dumpAll) {
10985        boolean needSep = false;
10986
10987        if (mLruProcesses.size() > 0) {
10988            if (needSep) pw.println();
10989            needSep = true;
10990            pw.println("  OOM levels:");
10991            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10992            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10993            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10994            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10995            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10996            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10997            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10998            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10999            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11000            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11001            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11002            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11003            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11004
11005            if (needSep) pw.println();
11006            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11007                    pw.print(" total, non-act at ");
11008                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11009                    pw.print(", non-svc at ");
11010                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11011                    pw.println("):");
11012            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11013            needSep = true;
11014        }
11015
11016        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11017
11018        pw.println();
11019        pw.println("  mHomeProcess: " + mHomeProcess);
11020        pw.println("  mPreviousProcess: " + mPreviousProcess);
11021        if (mHeavyWeightProcess != null) {
11022            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11023        }
11024
11025        return true;
11026    }
11027
11028    /**
11029     * There are three ways to call this:
11030     *  - no provider specified: dump all the providers
11031     *  - a flattened component name that matched an existing provider was specified as the
11032     *    first arg: dump that one provider
11033     *  - the first arg isn't the flattened component name of an existing provider:
11034     *    dump all providers whose component contains the first arg as a substring
11035     */
11036    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11037            int opti, boolean dumpAll) {
11038        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11039    }
11040
11041    static class ItemMatcher {
11042        ArrayList<ComponentName> components;
11043        ArrayList<String> strings;
11044        ArrayList<Integer> objects;
11045        boolean all;
11046
11047        ItemMatcher() {
11048            all = true;
11049        }
11050
11051        void build(String name) {
11052            ComponentName componentName = ComponentName.unflattenFromString(name);
11053            if (componentName != null) {
11054                if (components == null) {
11055                    components = new ArrayList<ComponentName>();
11056                }
11057                components.add(componentName);
11058                all = false;
11059            } else {
11060                int objectId = 0;
11061                // Not a '/' separated full component name; maybe an object ID?
11062                try {
11063                    objectId = Integer.parseInt(name, 16);
11064                    if (objects == null) {
11065                        objects = new ArrayList<Integer>();
11066                    }
11067                    objects.add(objectId);
11068                    all = false;
11069                } catch (RuntimeException e) {
11070                    // Not an integer; just do string match.
11071                    if (strings == null) {
11072                        strings = new ArrayList<String>();
11073                    }
11074                    strings.add(name);
11075                    all = false;
11076                }
11077            }
11078        }
11079
11080        int build(String[] args, int opti) {
11081            for (; opti<args.length; opti++) {
11082                String name = args[opti];
11083                if ("--".equals(name)) {
11084                    return opti+1;
11085                }
11086                build(name);
11087            }
11088            return opti;
11089        }
11090
11091        boolean match(Object object, ComponentName comp) {
11092            if (all) {
11093                return true;
11094            }
11095            if (components != null) {
11096                for (int i=0; i<components.size(); i++) {
11097                    if (components.get(i).equals(comp)) {
11098                        return true;
11099                    }
11100                }
11101            }
11102            if (objects != null) {
11103                for (int i=0; i<objects.size(); i++) {
11104                    if (System.identityHashCode(object) == objects.get(i)) {
11105                        return true;
11106                    }
11107                }
11108            }
11109            if (strings != null) {
11110                String flat = comp.flattenToString();
11111                for (int i=0; i<strings.size(); i++) {
11112                    if (flat.contains(strings.get(i))) {
11113                        return true;
11114                    }
11115                }
11116            }
11117            return false;
11118        }
11119    }
11120
11121    /**
11122     * There are three things that cmd can be:
11123     *  - a flattened component name that matches an existing activity
11124     *  - the cmd arg isn't the flattened component name of an existing activity:
11125     *    dump all activity whose component contains the cmd as a substring
11126     *  - A hex number of the ActivityRecord object instance.
11127     */
11128    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11129            int opti, boolean dumpAll) {
11130        ArrayList<ActivityRecord> activities;
11131
11132        synchronized (this) {
11133            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11134        }
11135
11136        if (activities.size() <= 0) {
11137            return false;
11138        }
11139
11140        String[] newArgs = new String[args.length - opti];
11141        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11142
11143        TaskRecord lastTask = null;
11144        boolean needSep = false;
11145        for (int i=activities.size()-1; i>=0; i--) {
11146            ActivityRecord r = activities.get(i);
11147            if (needSep) {
11148                pw.println();
11149            }
11150            needSep = true;
11151            synchronized (this) {
11152                if (lastTask != r.task) {
11153                    lastTask = r.task;
11154                    pw.print("TASK "); pw.print(lastTask.affinity);
11155                            pw.print(" id="); pw.println(lastTask.taskId);
11156                    if (dumpAll) {
11157                        lastTask.dump(pw, "  ");
11158                    }
11159                }
11160            }
11161            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11162        }
11163        return true;
11164    }
11165
11166    /**
11167     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11168     * there is a thread associated with the activity.
11169     */
11170    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11171            final ActivityRecord r, String[] args, boolean dumpAll) {
11172        String innerPrefix = prefix + "  ";
11173        synchronized (this) {
11174            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11175                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11176                    pw.print(" pid=");
11177                    if (r.app != null) pw.println(r.app.pid);
11178                    else pw.println("(not running)");
11179            if (dumpAll) {
11180                r.dump(pw, innerPrefix);
11181            }
11182        }
11183        if (r.app != null && r.app.thread != null) {
11184            // flush anything that is already in the PrintWriter since the thread is going
11185            // to write to the file descriptor directly
11186            pw.flush();
11187            try {
11188                TransferPipe tp = new TransferPipe();
11189                try {
11190                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11191                            r.appToken, innerPrefix, args);
11192                    tp.go(fd);
11193                } finally {
11194                    tp.kill();
11195                }
11196            } catch (IOException e) {
11197                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11198            } catch (RemoteException e) {
11199                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11200            }
11201        }
11202    }
11203
11204    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11205            int opti, boolean dumpAll, String dumpPackage) {
11206        boolean needSep = false;
11207        boolean onlyHistory = false;
11208        boolean printedAnything = false;
11209
11210        if ("history".equals(dumpPackage)) {
11211            if (opti < args.length && "-s".equals(args[opti])) {
11212                dumpAll = false;
11213            }
11214            onlyHistory = true;
11215            dumpPackage = null;
11216        }
11217
11218        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11219        if (!onlyHistory && dumpAll) {
11220            if (mRegisteredReceivers.size() > 0) {
11221                boolean printed = false;
11222                Iterator it = mRegisteredReceivers.values().iterator();
11223                while (it.hasNext()) {
11224                    ReceiverList r = (ReceiverList)it.next();
11225                    if (dumpPackage != null && (r.app == null ||
11226                            !dumpPackage.equals(r.app.info.packageName))) {
11227                        continue;
11228                    }
11229                    if (!printed) {
11230                        pw.println("  Registered Receivers:");
11231                        needSep = true;
11232                        printed = true;
11233                        printedAnything = true;
11234                    }
11235                    pw.print("  * "); pw.println(r);
11236                    r.dump(pw, "    ");
11237                }
11238            }
11239
11240            if (mReceiverResolver.dump(pw, needSep ?
11241                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11242                    "    ", dumpPackage, false)) {
11243                needSep = true;
11244                printedAnything = true;
11245            }
11246        }
11247
11248        for (BroadcastQueue q : mBroadcastQueues) {
11249            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11250            printedAnything |= needSep;
11251        }
11252
11253        needSep = true;
11254
11255        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11256            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11257                if (needSep) {
11258                    pw.println();
11259                }
11260                needSep = true;
11261                printedAnything = true;
11262                pw.print("  Sticky broadcasts for user ");
11263                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11264                StringBuilder sb = new StringBuilder(128);
11265                for (Map.Entry<String, ArrayList<Intent>> ent
11266                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11267                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11268                    if (dumpAll) {
11269                        pw.println(":");
11270                        ArrayList<Intent> intents = ent.getValue();
11271                        final int N = intents.size();
11272                        for (int i=0; i<N; i++) {
11273                            sb.setLength(0);
11274                            sb.append("    Intent: ");
11275                            intents.get(i).toShortString(sb, false, true, false, false);
11276                            pw.println(sb.toString());
11277                            Bundle bundle = intents.get(i).getExtras();
11278                            if (bundle != null) {
11279                                pw.print("      ");
11280                                pw.println(bundle.toString());
11281                            }
11282                        }
11283                    } else {
11284                        pw.println("");
11285                    }
11286                }
11287            }
11288        }
11289
11290        if (!onlyHistory && dumpAll) {
11291            pw.println();
11292            for (BroadcastQueue queue : mBroadcastQueues) {
11293                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11294                        + queue.mBroadcastsScheduled);
11295            }
11296            pw.println("  mHandler:");
11297            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11298            needSep = true;
11299            printedAnything = true;
11300        }
11301
11302        if (!printedAnything) {
11303            pw.println("  (nothing)");
11304        }
11305    }
11306
11307    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11308            int opti, boolean dumpAll, String dumpPackage) {
11309        boolean needSep;
11310        boolean printedAnything = false;
11311
11312        ItemMatcher matcher = new ItemMatcher();
11313        matcher.build(args, opti);
11314
11315        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11316
11317        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11318        printedAnything |= needSep;
11319
11320        if (mLaunchingProviders.size() > 0) {
11321            boolean printed = false;
11322            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11323                ContentProviderRecord r = mLaunchingProviders.get(i);
11324                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11325                    continue;
11326                }
11327                if (!printed) {
11328                    if (needSep) pw.println();
11329                    needSep = true;
11330                    pw.println("  Launching content providers:");
11331                    printed = true;
11332                    printedAnything = true;
11333                }
11334                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11335                        pw.println(r);
11336            }
11337        }
11338
11339        if (mGrantedUriPermissions.size() > 0) {
11340            boolean printed = false;
11341            int dumpUid = -2;
11342            if (dumpPackage != null) {
11343                try {
11344                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11345                } catch (NameNotFoundException e) {
11346                    dumpUid = -1;
11347                }
11348            }
11349            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11350                int uid = mGrantedUriPermissions.keyAt(i);
11351                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11352                    continue;
11353                }
11354                ArrayMap<Uri, UriPermission> perms
11355                        = mGrantedUriPermissions.valueAt(i);
11356                if (!printed) {
11357                    if (needSep) pw.println();
11358                    needSep = true;
11359                    pw.println("  Granted Uri Permissions:");
11360                    printed = true;
11361                    printedAnything = true;
11362                }
11363                pw.print("  * UID "); pw.print(uid);
11364                        pw.println(" holds:");
11365                for (UriPermission perm : perms.values()) {
11366                    pw.print("    "); pw.println(perm);
11367                    if (dumpAll) {
11368                        perm.dump(pw, "      ");
11369                    }
11370                }
11371            }
11372        }
11373
11374        if (!printedAnything) {
11375            pw.println("  (nothing)");
11376        }
11377    }
11378
11379    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11380            int opti, boolean dumpAll, String dumpPackage) {
11381        boolean printed = false;
11382
11383        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11384
11385        if (mIntentSenderRecords.size() > 0) {
11386            Iterator<WeakReference<PendingIntentRecord>> it
11387                    = mIntentSenderRecords.values().iterator();
11388            while (it.hasNext()) {
11389                WeakReference<PendingIntentRecord> ref = it.next();
11390                PendingIntentRecord rec = ref != null ? ref.get(): null;
11391                if (dumpPackage != null && (rec == null
11392                        || !dumpPackage.equals(rec.key.packageName))) {
11393                    continue;
11394                }
11395                printed = true;
11396                if (rec != null) {
11397                    pw.print("  * "); pw.println(rec);
11398                    if (dumpAll) {
11399                        rec.dump(pw, "    ");
11400                    }
11401                } else {
11402                    pw.print("  * "); pw.println(ref);
11403                }
11404            }
11405        }
11406
11407        if (!printed) {
11408            pw.println("  (nothing)");
11409        }
11410    }
11411
11412    private static final int dumpProcessList(PrintWriter pw,
11413            ActivityManagerService service, List list,
11414            String prefix, String normalLabel, String persistentLabel,
11415            String dumpPackage) {
11416        int numPers = 0;
11417        final int N = list.size()-1;
11418        for (int i=N; i>=0; i--) {
11419            ProcessRecord r = (ProcessRecord)list.get(i);
11420            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11421                continue;
11422            }
11423            pw.println(String.format("%s%s #%2d: %s",
11424                    prefix, (r.persistent ? persistentLabel : normalLabel),
11425                    i, r.toString()));
11426            if (r.persistent) {
11427                numPers++;
11428            }
11429        }
11430        return numPers;
11431    }
11432
11433    private static final boolean dumpProcessOomList(PrintWriter pw,
11434            ActivityManagerService service, List<ProcessRecord> origList,
11435            String prefix, String normalLabel, String persistentLabel,
11436            boolean inclDetails, String dumpPackage) {
11437
11438        ArrayList<Pair<ProcessRecord, Integer>> list
11439                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11440        for (int i=0; i<origList.size(); i++) {
11441            ProcessRecord r = origList.get(i);
11442            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11443                continue;
11444            }
11445            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11446        }
11447
11448        if (list.size() <= 0) {
11449            return false;
11450        }
11451
11452        Comparator<Pair<ProcessRecord, Integer>> comparator
11453                = new Comparator<Pair<ProcessRecord, Integer>>() {
11454            @Override
11455            public int compare(Pair<ProcessRecord, Integer> object1,
11456                    Pair<ProcessRecord, Integer> object2) {
11457                if (object1.first.setAdj != object2.first.setAdj) {
11458                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11459                }
11460                if (object1.second.intValue() != object2.second.intValue()) {
11461                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11462                }
11463                return 0;
11464            }
11465        };
11466
11467        Collections.sort(list, comparator);
11468
11469        final long curRealtime = SystemClock.elapsedRealtime();
11470        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11471        final long curUptime = SystemClock.uptimeMillis();
11472        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11473
11474        for (int i=list.size()-1; i>=0; i--) {
11475            ProcessRecord r = list.get(i).first;
11476            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11477            char schedGroup;
11478            switch (r.setSchedGroup) {
11479                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11480                    schedGroup = 'B';
11481                    break;
11482                case Process.THREAD_GROUP_DEFAULT:
11483                    schedGroup = 'F';
11484                    break;
11485                default:
11486                    schedGroup = '?';
11487                    break;
11488            }
11489            char foreground;
11490            if (r.foregroundActivities) {
11491                foreground = 'A';
11492            } else if (r.foregroundServices) {
11493                foreground = 'S';
11494            } else {
11495                foreground = ' ';
11496            }
11497            String procState = ProcessList.makeProcStateString(r.curProcState);
11498            pw.print(prefix);
11499            pw.print(r.persistent ? persistentLabel : normalLabel);
11500            pw.print(" #");
11501            int num = (origList.size()-1)-list.get(i).second;
11502            if (num < 10) pw.print(' ');
11503            pw.print(num);
11504            pw.print(": ");
11505            pw.print(oomAdj);
11506            pw.print(' ');
11507            pw.print(schedGroup);
11508            pw.print('/');
11509            pw.print(foreground);
11510            pw.print('/');
11511            pw.print(procState);
11512            pw.print(" trm:");
11513            if (r.trimMemoryLevel < 10) pw.print(' ');
11514            pw.print(r.trimMemoryLevel);
11515            pw.print(' ');
11516            pw.print(r.toShortString());
11517            pw.print(" (");
11518            pw.print(r.adjType);
11519            pw.println(')');
11520            if (r.adjSource != null || r.adjTarget != null) {
11521                pw.print(prefix);
11522                pw.print("    ");
11523                if (r.adjTarget instanceof ComponentName) {
11524                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11525                } else if (r.adjTarget != null) {
11526                    pw.print(r.adjTarget.toString());
11527                } else {
11528                    pw.print("{null}");
11529                }
11530                pw.print("<=");
11531                if (r.adjSource instanceof ProcessRecord) {
11532                    pw.print("Proc{");
11533                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11534                    pw.println("}");
11535                } else if (r.adjSource != null) {
11536                    pw.println(r.adjSource.toString());
11537                } else {
11538                    pw.println("{null}");
11539                }
11540            }
11541            if (inclDetails) {
11542                pw.print(prefix);
11543                pw.print("    ");
11544                pw.print("oom: max="); pw.print(r.maxAdj);
11545                pw.print(" curRaw="); pw.print(r.curRawAdj);
11546                pw.print(" setRaw="); pw.print(r.setRawAdj);
11547                pw.print(" cur="); pw.print(r.curAdj);
11548                pw.print(" set="); pw.println(r.setAdj);
11549                pw.print(prefix);
11550                pw.print("    ");
11551                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11552                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11553                pw.print(" lastPss="); pw.print(r.lastPss);
11554                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11555                pw.print(prefix);
11556                pw.print("    ");
11557                pw.print("keeping="); pw.print(r.keeping);
11558                pw.print(" cached="); pw.print(r.cached);
11559                pw.print(" empty="); pw.print(r.empty);
11560                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11561
11562                if (!r.keeping) {
11563                    if (r.lastWakeTime != 0) {
11564                        long wtime;
11565                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11566                        synchronized (stats) {
11567                            wtime = stats.getProcessWakeTime(r.info.uid,
11568                                    r.pid, curRealtime);
11569                        }
11570                        long timeUsed = wtime - r.lastWakeTime;
11571                        pw.print(prefix);
11572                        pw.print("    ");
11573                        pw.print("keep awake over ");
11574                        TimeUtils.formatDuration(realtimeSince, pw);
11575                        pw.print(" used ");
11576                        TimeUtils.formatDuration(timeUsed, pw);
11577                        pw.print(" (");
11578                        pw.print((timeUsed*100)/realtimeSince);
11579                        pw.println("%)");
11580                    }
11581                    if (r.lastCpuTime != 0) {
11582                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11583                        pw.print(prefix);
11584                        pw.print("    ");
11585                        pw.print("run cpu over ");
11586                        TimeUtils.formatDuration(uptimeSince, pw);
11587                        pw.print(" used ");
11588                        TimeUtils.formatDuration(timeUsed, pw);
11589                        pw.print(" (");
11590                        pw.print((timeUsed*100)/uptimeSince);
11591                        pw.println("%)");
11592                    }
11593                }
11594            }
11595        }
11596        return true;
11597    }
11598
11599    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11600        ArrayList<ProcessRecord> procs;
11601        synchronized (this) {
11602            if (args != null && args.length > start
11603                    && args[start].charAt(0) != '-') {
11604                procs = new ArrayList<ProcessRecord>();
11605                int pid = -1;
11606                try {
11607                    pid = Integer.parseInt(args[start]);
11608                } catch (NumberFormatException e) {
11609                }
11610                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11611                    ProcessRecord proc = mLruProcesses.get(i);
11612                    if (proc.pid == pid) {
11613                        procs.add(proc);
11614                    } else if (proc.processName.equals(args[start])) {
11615                        procs.add(proc);
11616                    }
11617                }
11618                if (procs.size() <= 0) {
11619                    return null;
11620                }
11621            } else {
11622                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11623            }
11624        }
11625        return procs;
11626    }
11627
11628    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11629            PrintWriter pw, String[] args) {
11630        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11631        if (procs == null) {
11632            pw.println("No process found for: " + args[0]);
11633            return;
11634        }
11635
11636        long uptime = SystemClock.uptimeMillis();
11637        long realtime = SystemClock.elapsedRealtime();
11638        pw.println("Applications Graphics Acceleration Info:");
11639        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11640
11641        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11642            ProcessRecord r = procs.get(i);
11643            if (r.thread != null) {
11644                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11645                pw.flush();
11646                try {
11647                    TransferPipe tp = new TransferPipe();
11648                    try {
11649                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11650                        tp.go(fd);
11651                    } finally {
11652                        tp.kill();
11653                    }
11654                } catch (IOException e) {
11655                    pw.println("Failure while dumping the app: " + r);
11656                    pw.flush();
11657                } catch (RemoteException e) {
11658                    pw.println("Got a RemoteException while dumping the app " + r);
11659                    pw.flush();
11660                }
11661            }
11662        }
11663    }
11664
11665    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11666        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11667        if (procs == null) {
11668            pw.println("No process found for: " + args[0]);
11669            return;
11670        }
11671
11672        pw.println("Applications Database Info:");
11673
11674        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11675            ProcessRecord r = procs.get(i);
11676            if (r.thread != null) {
11677                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11678                pw.flush();
11679                try {
11680                    TransferPipe tp = new TransferPipe();
11681                    try {
11682                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11683                        tp.go(fd);
11684                    } finally {
11685                        tp.kill();
11686                    }
11687                } catch (IOException e) {
11688                    pw.println("Failure while dumping the app: " + r);
11689                    pw.flush();
11690                } catch (RemoteException e) {
11691                    pw.println("Got a RemoteException while dumping the app " + r);
11692                    pw.flush();
11693                }
11694            }
11695        }
11696    }
11697
11698    final static class MemItem {
11699        final boolean isProc;
11700        final String label;
11701        final String shortLabel;
11702        final long pss;
11703        final int id;
11704        final boolean hasActivities;
11705        ArrayList<MemItem> subitems;
11706
11707        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11708                boolean _hasActivities) {
11709            isProc = true;
11710            label = _label;
11711            shortLabel = _shortLabel;
11712            pss = _pss;
11713            id = _id;
11714            hasActivities = _hasActivities;
11715        }
11716
11717        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11718            isProc = false;
11719            label = _label;
11720            shortLabel = _shortLabel;
11721            pss = _pss;
11722            id = _id;
11723            hasActivities = false;
11724        }
11725    }
11726
11727    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11728            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11729        if (sort && !isCompact) {
11730            Collections.sort(items, new Comparator<MemItem>() {
11731                @Override
11732                public int compare(MemItem lhs, MemItem rhs) {
11733                    if (lhs.pss < rhs.pss) {
11734                        return 1;
11735                    } else if (lhs.pss > rhs.pss) {
11736                        return -1;
11737                    }
11738                    return 0;
11739                }
11740            });
11741        }
11742
11743        for (int i=0; i<items.size(); i++) {
11744            MemItem mi = items.get(i);
11745            if (!isCompact) {
11746                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11747            } else if (mi.isProc) {
11748                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11749                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11750                pw.println(mi.hasActivities ? ",a" : ",e");
11751            } else {
11752                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11753                pw.println(mi.pss);
11754            }
11755            if (mi.subitems != null) {
11756                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11757                        true, isCompact);
11758            }
11759        }
11760    }
11761
11762    // These are in KB.
11763    static final long[] DUMP_MEM_BUCKETS = new long[] {
11764        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11765        120*1024, 160*1024, 200*1024,
11766        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11767        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11768    };
11769
11770    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11771            boolean stackLike) {
11772        int start = label.lastIndexOf('.');
11773        if (start >= 0) start++;
11774        else start = 0;
11775        int end = label.length();
11776        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11777            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11778                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11779                out.append(bucket);
11780                out.append(stackLike ? "MB." : "MB ");
11781                out.append(label, start, end);
11782                return;
11783            }
11784        }
11785        out.append(memKB/1024);
11786        out.append(stackLike ? "MB." : "MB ");
11787        out.append(label, start, end);
11788    }
11789
11790    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11791            ProcessList.NATIVE_ADJ,
11792            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11793            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11794            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11795            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11796            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11797    };
11798    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11799            "Native",
11800            "System", "Persistent", "Foreground",
11801            "Visible", "Perceptible",
11802            "Heavy Weight", "Backup",
11803            "A Services", "Home",
11804            "Previous", "B Services", "Cached"
11805    };
11806    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11807            "native",
11808            "sys", "pers", "fore",
11809            "vis", "percept",
11810            "heavy", "backup",
11811            "servicea", "home",
11812            "prev", "serviceb", "cached"
11813    };
11814
11815    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11816            long realtime, boolean isCheckinRequest, boolean isCompact) {
11817        if (isCheckinRequest || isCompact) {
11818            // short checkin version
11819            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11820        } else {
11821            pw.println("Applications Memory Usage (kB):");
11822            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11823        }
11824    }
11825
11826    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11827            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11828        boolean dumpDetails = false;
11829        boolean dumpFullDetails = false;
11830        boolean dumpDalvik = false;
11831        boolean oomOnly = false;
11832        boolean isCompact = false;
11833        boolean localOnly = false;
11834
11835        int opti = 0;
11836        while (opti < args.length) {
11837            String opt = args[opti];
11838            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11839                break;
11840            }
11841            opti++;
11842            if ("-a".equals(opt)) {
11843                dumpDetails = true;
11844                dumpFullDetails = true;
11845                dumpDalvik = true;
11846            } else if ("-d".equals(opt)) {
11847                dumpDalvik = true;
11848            } else if ("-c".equals(opt)) {
11849                isCompact = true;
11850            } else if ("--oom".equals(opt)) {
11851                oomOnly = true;
11852            } else if ("--local".equals(opt)) {
11853                localOnly = true;
11854            } else if ("-h".equals(opt)) {
11855                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11856                pw.println("  -a: include all available information for each process.");
11857                pw.println("  -d: include dalvik details when dumping process details.");
11858                pw.println("  -c: dump in a compact machine-parseable representation.");
11859                pw.println("  --oom: only show processes organized by oom adj.");
11860                pw.println("  --local: only collect details locally, don't call process.");
11861                pw.println("If [process] is specified it can be the name or ");
11862                pw.println("pid of a specific process to dump.");
11863                return;
11864            } else {
11865                pw.println("Unknown argument: " + opt + "; use -h for help");
11866            }
11867        }
11868
11869        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11870        long uptime = SystemClock.uptimeMillis();
11871        long realtime = SystemClock.elapsedRealtime();
11872        final long[] tmpLong = new long[1];
11873
11874        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11875        if (procs == null) {
11876            // No Java processes.  Maybe they want to print a native process.
11877            if (args != null && args.length > opti
11878                    && args[opti].charAt(0) != '-') {
11879                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11880                        = new ArrayList<ProcessCpuTracker.Stats>();
11881                updateCpuStatsNow();
11882                int findPid = -1;
11883                try {
11884                    findPid = Integer.parseInt(args[opti]);
11885                } catch (NumberFormatException e) {
11886                }
11887                synchronized (mProcessCpuThread) {
11888                    final int N = mProcessCpuTracker.countStats();
11889                    for (int i=0; i<N; i++) {
11890                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11891                        if (st.pid == findPid || (st.baseName != null
11892                                && st.baseName.equals(args[opti]))) {
11893                            nativeProcs.add(st);
11894                        }
11895                    }
11896                }
11897                if (nativeProcs.size() > 0) {
11898                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11899                            isCompact);
11900                    Debug.MemoryInfo mi = null;
11901                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11902                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11903                        final int pid = r.pid;
11904                        if (!isCheckinRequest && dumpDetails) {
11905                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11906                        }
11907                        if (mi == null) {
11908                            mi = new Debug.MemoryInfo();
11909                        }
11910                        if (dumpDetails || (!brief && !oomOnly)) {
11911                            Debug.getMemoryInfo(pid, mi);
11912                        } else {
11913                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11914                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11915                        }
11916                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11917                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11918                        if (isCheckinRequest) {
11919                            pw.println();
11920                        }
11921                    }
11922                    return;
11923                }
11924            }
11925            pw.println("No process found for: " + args[opti]);
11926            return;
11927        }
11928
11929        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11930            dumpDetails = true;
11931        }
11932
11933        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11934
11935        String[] innerArgs = new String[args.length-opti];
11936        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11937
11938        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11939        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11940        long nativePss=0, dalvikPss=0, otherPss=0;
11941        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11942
11943        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11944        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11945                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11946
11947        long totalPss = 0;
11948        long cachedPss = 0;
11949
11950        Debug.MemoryInfo mi = null;
11951        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11952            final ProcessRecord r = procs.get(i);
11953            final IApplicationThread thread;
11954            final int pid;
11955            final int oomAdj;
11956            final boolean hasActivities;
11957            synchronized (this) {
11958                thread = r.thread;
11959                pid = r.pid;
11960                oomAdj = r.getSetAdjWithServices();
11961                hasActivities = r.activities.size() > 0;
11962            }
11963            if (thread != null) {
11964                if (!isCheckinRequest && dumpDetails) {
11965                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11966                }
11967                if (mi == null) {
11968                    mi = new Debug.MemoryInfo();
11969                }
11970                if (dumpDetails || (!brief && !oomOnly)) {
11971                    Debug.getMemoryInfo(pid, mi);
11972                } else {
11973                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11974                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11975                }
11976                if (dumpDetails) {
11977                    if (localOnly) {
11978                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11979                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11980                        if (isCheckinRequest) {
11981                            pw.println();
11982                        }
11983                    } else {
11984                        try {
11985                            pw.flush();
11986                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11987                                    dumpDalvik, innerArgs);
11988                        } catch (RemoteException e) {
11989                            if (!isCheckinRequest) {
11990                                pw.println("Got RemoteException!");
11991                                pw.flush();
11992                            }
11993                        }
11994                    }
11995                }
11996
11997                final long myTotalPss = mi.getTotalPss();
11998                final long myTotalUss = mi.getTotalUss();
11999
12000                synchronized (this) {
12001                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12002                        // Record this for posterity if the process has been stable.
12003                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12004                    }
12005                }
12006
12007                if (!isCheckinRequest && mi != null) {
12008                    totalPss += myTotalPss;
12009                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12010                            (hasActivities ? " / activities)" : ")"),
12011                            r.processName, myTotalPss, pid, hasActivities);
12012                    procMems.add(pssItem);
12013                    procMemsMap.put(pid, pssItem);
12014
12015                    nativePss += mi.nativePss;
12016                    dalvikPss += mi.dalvikPss;
12017                    otherPss += mi.otherPss;
12018                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12019                        long mem = mi.getOtherPss(j);
12020                        miscPss[j] += mem;
12021                        otherPss -= mem;
12022                    }
12023
12024                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12025                        cachedPss += myTotalPss;
12026                    }
12027
12028                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12029                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12030                                || oomIndex == (oomPss.length-1)) {
12031                            oomPss[oomIndex] += myTotalPss;
12032                            if (oomProcs[oomIndex] == null) {
12033                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12034                            }
12035                            oomProcs[oomIndex].add(pssItem);
12036                            break;
12037                        }
12038                    }
12039                }
12040            }
12041        }
12042
12043        if (!isCheckinRequest && procs.size() > 1) {
12044            // If we are showing aggregations, also look for native processes to
12045            // include so that our aggregations are more accurate.
12046            updateCpuStatsNow();
12047            synchronized (mProcessCpuThread) {
12048                final int N = mProcessCpuTracker.countStats();
12049                for (int i=0; i<N; i++) {
12050                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12051                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12052                        if (mi == null) {
12053                            mi = new Debug.MemoryInfo();
12054                        }
12055                        if (!brief && !oomOnly) {
12056                            Debug.getMemoryInfo(st.pid, mi);
12057                        } else {
12058                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12059                            mi.nativePrivateDirty = (int)tmpLong[0];
12060                        }
12061
12062                        final long myTotalPss = mi.getTotalPss();
12063                        totalPss += myTotalPss;
12064
12065                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12066                                st.name, myTotalPss, st.pid, false);
12067                        procMems.add(pssItem);
12068
12069                        nativePss += mi.nativePss;
12070                        dalvikPss += mi.dalvikPss;
12071                        otherPss += mi.otherPss;
12072                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12073                            long mem = mi.getOtherPss(j);
12074                            miscPss[j] += mem;
12075                            otherPss -= mem;
12076                        }
12077                        oomPss[0] += myTotalPss;
12078                        if (oomProcs[0] == null) {
12079                            oomProcs[0] = new ArrayList<MemItem>();
12080                        }
12081                        oomProcs[0].add(pssItem);
12082                    }
12083                }
12084            }
12085
12086            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12087
12088            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12089            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12090            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12091            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12092                String label = Debug.MemoryInfo.getOtherLabel(j);
12093                catMems.add(new MemItem(label, label, miscPss[j], j));
12094            }
12095
12096            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12097            for (int j=0; j<oomPss.length; j++) {
12098                if (oomPss[j] != 0) {
12099                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12100                            : DUMP_MEM_OOM_LABEL[j];
12101                    MemItem item = new MemItem(label, label, oomPss[j],
12102                            DUMP_MEM_OOM_ADJ[j]);
12103                    item.subitems = oomProcs[j];
12104                    oomMems.add(item);
12105                }
12106            }
12107
12108            if (!brief && !oomOnly && !isCompact) {
12109                pw.println();
12110                pw.println("Total PSS by process:");
12111                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12112                pw.println();
12113            }
12114            if (!isCompact) {
12115                pw.println("Total PSS by OOM adjustment:");
12116            }
12117            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12118            if (!brief && !oomOnly) {
12119                PrintWriter out = categoryPw != null ? categoryPw : pw;
12120                if (!isCompact) {
12121                    out.println();
12122                    out.println("Total PSS by category:");
12123                }
12124                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12125            }
12126            if (!isCompact) {
12127                pw.println();
12128            }
12129            MemInfoReader memInfo = new MemInfoReader();
12130            memInfo.readMemInfo();
12131            if (!brief) {
12132                if (!isCompact) {
12133                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12134                    pw.println(" kB");
12135                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12136                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12137                            pw.print(cachedPss); pw.print(" cached pss + ");
12138                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12139                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12140                } else {
12141                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12142                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12143                            + memInfo.getFreeSizeKb()); pw.print(",");
12144                    pw.println(totalPss - cachedPss);
12145                }
12146            }
12147            if (!isCompact) {
12148                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12149                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12150                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12151                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12152                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12153                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12154                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12155                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12156                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12157                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12158                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12159            }
12160            if (!brief) {
12161                if (memInfo.getZramTotalSizeKb() != 0) {
12162                    if (!isCompact) {
12163                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12164                                pw.print(" kB physical used for ");
12165                                pw.print(memInfo.getSwapTotalSizeKb()
12166                                        - memInfo.getSwapFreeSizeKb());
12167                                pw.print(" kB in swap (");
12168                                pw.print(memInfo.getSwapTotalSizeKb());
12169                                pw.println(" kB total swap)");
12170                    } else {
12171                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12172                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12173                                pw.println(memInfo.getSwapFreeSizeKb());
12174                    }
12175                }
12176                final int[] SINGLE_LONG_FORMAT = new int[] {
12177                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12178                };
12179                long[] longOut = new long[1];
12180                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12181                        SINGLE_LONG_FORMAT, null, longOut, null);
12182                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12183                longOut[0] = 0;
12184                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12185                        SINGLE_LONG_FORMAT, null, longOut, null);
12186                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12187                longOut[0] = 0;
12188                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12189                        SINGLE_LONG_FORMAT, null, longOut, null);
12190                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12191                longOut[0] = 0;
12192                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12193                        SINGLE_LONG_FORMAT, null, longOut, null);
12194                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12195                if (!isCompact) {
12196                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12197                        pw.print("      KSM: "); pw.print(sharing);
12198                                pw.print(" kB saved from shared ");
12199                                pw.print(shared); pw.println(" kB");
12200                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12201                                pw.print(voltile); pw.println(" kB volatile");
12202                    }
12203                    pw.print("   Tuning: ");
12204                    pw.print(ActivityManager.staticGetMemoryClass());
12205                    pw.print(" (large ");
12206                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12207                    pw.print("), oom ");
12208                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12209                    pw.print(" kB");
12210                    pw.print(", restore limit ");
12211                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12212                    pw.print(" kB");
12213                    if (ActivityManager.isLowRamDeviceStatic()) {
12214                        pw.print(" (low-ram)");
12215                    }
12216                    if (ActivityManager.isHighEndGfx()) {
12217                        pw.print(" (high-end-gfx)");
12218                    }
12219                    pw.println();
12220                } else {
12221                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12222                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12223                    pw.println(voltile);
12224                    pw.print("tuning,");
12225                    pw.print(ActivityManager.staticGetMemoryClass());
12226                    pw.print(',');
12227                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12228                    pw.print(',');
12229                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12230                    if (ActivityManager.isLowRamDeviceStatic()) {
12231                        pw.print(",low-ram");
12232                    }
12233                    if (ActivityManager.isHighEndGfx()) {
12234                        pw.print(",high-end-gfx");
12235                    }
12236                    pw.println();
12237                }
12238            }
12239        }
12240    }
12241
12242    /**
12243     * Searches array of arguments for the specified string
12244     * @param args array of argument strings
12245     * @param value value to search for
12246     * @return true if the value is contained in the array
12247     */
12248    private static boolean scanArgs(String[] args, String value) {
12249        if (args != null) {
12250            for (String arg : args) {
12251                if (value.equals(arg)) {
12252                    return true;
12253                }
12254            }
12255        }
12256        return false;
12257    }
12258
12259    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12260            ContentProviderRecord cpr, boolean always) {
12261        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12262
12263        if (!inLaunching || always) {
12264            synchronized (cpr) {
12265                cpr.launchingApp = null;
12266                cpr.notifyAll();
12267            }
12268            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12269            String names[] = cpr.info.authority.split(";");
12270            for (int j = 0; j < names.length; j++) {
12271                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12272            }
12273        }
12274
12275        for (int i=0; i<cpr.connections.size(); i++) {
12276            ContentProviderConnection conn = cpr.connections.get(i);
12277            if (conn.waiting) {
12278                // If this connection is waiting for the provider, then we don't
12279                // need to mess with its process unless we are always removing
12280                // or for some reason the provider is not currently launching.
12281                if (inLaunching && !always) {
12282                    continue;
12283                }
12284            }
12285            ProcessRecord capp = conn.client;
12286            conn.dead = true;
12287            if (conn.stableCount > 0) {
12288                if (!capp.persistent && capp.thread != null
12289                        && capp.pid != 0
12290                        && capp.pid != MY_PID) {
12291                    killUnneededProcessLocked(capp, "depends on provider "
12292                            + cpr.name.flattenToShortString()
12293                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12294                }
12295            } else if (capp.thread != null && conn.provider.provider != null) {
12296                try {
12297                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12298                } catch (RemoteException e) {
12299                }
12300                // In the protocol here, we don't expect the client to correctly
12301                // clean up this connection, we'll just remove it.
12302                cpr.connections.remove(i);
12303                conn.client.conProviders.remove(conn);
12304            }
12305        }
12306
12307        if (inLaunching && always) {
12308            mLaunchingProviders.remove(cpr);
12309        }
12310        return inLaunching;
12311    }
12312
12313    /**
12314     * Main code for cleaning up a process when it has gone away.  This is
12315     * called both as a result of the process dying, or directly when stopping
12316     * a process when running in single process mode.
12317     */
12318    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12319            boolean restarting, boolean allowRestart, int index) {
12320        if (index >= 0) {
12321            removeLruProcessLocked(app);
12322        }
12323
12324        mProcessesToGc.remove(app);
12325        mPendingPssProcesses.remove(app);
12326
12327        // Dismiss any open dialogs.
12328        if (app.crashDialog != null && !app.forceCrashReport) {
12329            app.crashDialog.dismiss();
12330            app.crashDialog = null;
12331        }
12332        if (app.anrDialog != null) {
12333            app.anrDialog.dismiss();
12334            app.anrDialog = null;
12335        }
12336        if (app.waitDialog != null) {
12337            app.waitDialog.dismiss();
12338            app.waitDialog = null;
12339        }
12340
12341        app.crashing = false;
12342        app.notResponding = false;
12343
12344        app.resetPackageList(mProcessStats);
12345        app.unlinkDeathRecipient();
12346        app.makeInactive(mProcessStats);
12347        app.forcingToForeground = null;
12348        app.foregroundServices = false;
12349        app.foregroundActivities = false;
12350        app.hasShownUi = false;
12351        app.hasAboveClient = false;
12352
12353        mServices.killServicesLocked(app, allowRestart);
12354
12355        boolean restart = false;
12356
12357        // Remove published content providers.
12358        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12359            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12360            final boolean always = app.bad || !allowRestart;
12361            if (removeDyingProviderLocked(app, cpr, always) || always) {
12362                // We left the provider in the launching list, need to
12363                // restart it.
12364                restart = true;
12365            }
12366
12367            cpr.provider = null;
12368            cpr.proc = null;
12369        }
12370        app.pubProviders.clear();
12371
12372        // Take care of any launching providers waiting for this process.
12373        if (checkAppInLaunchingProvidersLocked(app, false)) {
12374            restart = true;
12375        }
12376
12377        // Unregister from connected content providers.
12378        if (!app.conProviders.isEmpty()) {
12379            for (int i=0; i<app.conProviders.size(); i++) {
12380                ContentProviderConnection conn = app.conProviders.get(i);
12381                conn.provider.connections.remove(conn);
12382            }
12383            app.conProviders.clear();
12384        }
12385
12386        // At this point there may be remaining entries in mLaunchingProviders
12387        // where we were the only one waiting, so they are no longer of use.
12388        // Look for these and clean up if found.
12389        // XXX Commented out for now.  Trying to figure out a way to reproduce
12390        // the actual situation to identify what is actually going on.
12391        if (false) {
12392            for (int i=0; i<mLaunchingProviders.size(); i++) {
12393                ContentProviderRecord cpr = (ContentProviderRecord)
12394                        mLaunchingProviders.get(i);
12395                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12396                    synchronized (cpr) {
12397                        cpr.launchingApp = null;
12398                        cpr.notifyAll();
12399                    }
12400                }
12401            }
12402        }
12403
12404        skipCurrentReceiverLocked(app);
12405
12406        // Unregister any receivers.
12407        for (int i=app.receivers.size()-1; i>=0; i--) {
12408            removeReceiverLocked(app.receivers.valueAt(i));
12409        }
12410        app.receivers.clear();
12411
12412        // If the app is undergoing backup, tell the backup manager about it
12413        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12414            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12415                    + mBackupTarget.appInfo + " died during backup");
12416            try {
12417                IBackupManager bm = IBackupManager.Stub.asInterface(
12418                        ServiceManager.getService(Context.BACKUP_SERVICE));
12419                bm.agentDisconnected(app.info.packageName);
12420            } catch (RemoteException e) {
12421                // can't happen; backup manager is local
12422            }
12423        }
12424
12425        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12426            ProcessChangeItem item = mPendingProcessChanges.get(i);
12427            if (item.pid == app.pid) {
12428                mPendingProcessChanges.remove(i);
12429                mAvailProcessChanges.add(item);
12430            }
12431        }
12432        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12433
12434        // If the caller is restarting this app, then leave it in its
12435        // current lists and let the caller take care of it.
12436        if (restarting) {
12437            return;
12438        }
12439
12440        if (!app.persistent || app.isolated) {
12441            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12442                    "Removing non-persistent process during cleanup: " + app);
12443            mProcessNames.remove(app.processName, app.uid);
12444            mIsolatedProcesses.remove(app.uid);
12445            if (mHeavyWeightProcess == app) {
12446                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12447                        mHeavyWeightProcess.userId, 0));
12448                mHeavyWeightProcess = null;
12449            }
12450        } else if (!app.removed) {
12451            // This app is persistent, so we need to keep its record around.
12452            // If it is not already on the pending app list, add it there
12453            // and start a new process for it.
12454            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12455                mPersistentStartingProcesses.add(app);
12456                restart = true;
12457            }
12458        }
12459        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12460                "Clean-up removing on hold: " + app);
12461        mProcessesOnHold.remove(app);
12462
12463        if (app == mHomeProcess) {
12464            mHomeProcess = null;
12465        }
12466        if (app == mPreviousProcess) {
12467            mPreviousProcess = null;
12468        }
12469
12470        if (restart && !app.isolated) {
12471            // We have components that still need to be running in the
12472            // process, so re-launch it.
12473            mProcessNames.put(app.processName, app.uid, app);
12474            startProcessLocked(app, "restart", app.processName);
12475        } else if (app.pid > 0 && app.pid != MY_PID) {
12476            // Goodbye!
12477            synchronized (mPidsSelfLocked) {
12478                mPidsSelfLocked.remove(app.pid);
12479                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12480            }
12481            app.setPid(0);
12482        }
12483    }
12484
12485    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12486        // Look through the content providers we are waiting to have launched,
12487        // and if any run in this process then either schedule a restart of
12488        // the process or kill the client waiting for it if this process has
12489        // gone bad.
12490        int NL = mLaunchingProviders.size();
12491        boolean restart = false;
12492        for (int i=0; i<NL; i++) {
12493            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12494            if (cpr.launchingApp == app) {
12495                if (!alwaysBad && !app.bad) {
12496                    restart = true;
12497                } else {
12498                    removeDyingProviderLocked(app, cpr, true);
12499                    // cpr should have been removed from mLaunchingProviders
12500                    NL = mLaunchingProviders.size();
12501                    i--;
12502                }
12503            }
12504        }
12505        return restart;
12506    }
12507
12508    // =========================================================
12509    // SERVICES
12510    // =========================================================
12511
12512    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12513            int flags) {
12514        enforceNotIsolatedCaller("getServices");
12515        synchronized (this) {
12516            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12517        }
12518    }
12519
12520    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12521        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12522        synchronized (this) {
12523            return mServices.getRunningServiceControlPanelLocked(name);
12524        }
12525    }
12526
12527    public ComponentName startService(IApplicationThread caller, Intent service,
12528            String resolvedType, int userId) {
12529        enforceNotIsolatedCaller("startService");
12530        // Refuse possible leaked file descriptors
12531        if (service != null && service.hasFileDescriptors() == true) {
12532            throw new IllegalArgumentException("File descriptors passed in Intent");
12533        }
12534
12535        if (DEBUG_SERVICE)
12536            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12537        synchronized(this) {
12538            final int callingPid = Binder.getCallingPid();
12539            final int callingUid = Binder.getCallingUid();
12540            final long origId = Binder.clearCallingIdentity();
12541            ComponentName res = mServices.startServiceLocked(caller, service,
12542                    resolvedType, callingPid, callingUid, userId);
12543            Binder.restoreCallingIdentity(origId);
12544            return res;
12545        }
12546    }
12547
12548    ComponentName startServiceInPackage(int uid,
12549            Intent service, String resolvedType, int userId) {
12550        synchronized(this) {
12551            if (DEBUG_SERVICE)
12552                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12553            final long origId = Binder.clearCallingIdentity();
12554            ComponentName res = mServices.startServiceLocked(null, service,
12555                    resolvedType, -1, uid, userId);
12556            Binder.restoreCallingIdentity(origId);
12557            return res;
12558        }
12559    }
12560
12561    public int stopService(IApplicationThread caller, Intent service,
12562            String resolvedType, int userId) {
12563        enforceNotIsolatedCaller("stopService");
12564        // Refuse possible leaked file descriptors
12565        if (service != null && service.hasFileDescriptors() == true) {
12566            throw new IllegalArgumentException("File descriptors passed in Intent");
12567        }
12568
12569        synchronized(this) {
12570            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12571        }
12572    }
12573
12574    public IBinder peekService(Intent service, String resolvedType) {
12575        enforceNotIsolatedCaller("peekService");
12576        // Refuse possible leaked file descriptors
12577        if (service != null && service.hasFileDescriptors() == true) {
12578            throw new IllegalArgumentException("File descriptors passed in Intent");
12579        }
12580        synchronized(this) {
12581            return mServices.peekServiceLocked(service, resolvedType);
12582        }
12583    }
12584
12585    public boolean stopServiceToken(ComponentName className, IBinder token,
12586            int startId) {
12587        synchronized(this) {
12588            return mServices.stopServiceTokenLocked(className, token, startId);
12589        }
12590    }
12591
12592    public void setServiceForeground(ComponentName className, IBinder token,
12593            int id, Notification notification, boolean removeNotification) {
12594        synchronized(this) {
12595            mServices.setServiceForegroundLocked(className, token, id, notification,
12596                    removeNotification);
12597        }
12598    }
12599
12600    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12601            boolean requireFull, String name, String callerPackage) {
12602        final int callingUserId = UserHandle.getUserId(callingUid);
12603        if (callingUserId != userId) {
12604            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12605                if ((requireFull || checkComponentPermission(
12606                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12607                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12608                        && checkComponentPermission(
12609                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12610                                callingPid, callingUid, -1, true)
12611                                != PackageManager.PERMISSION_GRANTED) {
12612                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12613                        // In this case, they would like to just execute as their
12614                        // owner user instead of failing.
12615                        userId = callingUserId;
12616                    } else {
12617                        StringBuilder builder = new StringBuilder(128);
12618                        builder.append("Permission Denial: ");
12619                        builder.append(name);
12620                        if (callerPackage != null) {
12621                            builder.append(" from ");
12622                            builder.append(callerPackage);
12623                        }
12624                        builder.append(" asks to run as user ");
12625                        builder.append(userId);
12626                        builder.append(" but is calling from user ");
12627                        builder.append(UserHandle.getUserId(callingUid));
12628                        builder.append("; this requires ");
12629                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12630                        if (!requireFull) {
12631                            builder.append(" or ");
12632                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12633                        }
12634                        String msg = builder.toString();
12635                        Slog.w(TAG, msg);
12636                        throw new SecurityException(msg);
12637                    }
12638                }
12639            }
12640            if (userId == UserHandle.USER_CURRENT
12641                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12642                // Note that we may be accessing this outside of a lock...
12643                // shouldn't be a big deal, if this is being called outside
12644                // of a locked context there is intrinsically a race with
12645                // the value the caller will receive and someone else changing it.
12646                userId = mCurrentUserId;
12647            }
12648            if (!allowAll && userId < 0) {
12649                throw new IllegalArgumentException(
12650                        "Call does not support special user #" + userId);
12651            }
12652        }
12653        return userId;
12654    }
12655
12656    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12657            String className, int flags) {
12658        boolean result = false;
12659        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12660            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12661                if (ActivityManager.checkUidPermission(
12662                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12663                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12664                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12665                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12666                            + " requests FLAG_SINGLE_USER, but app does not hold "
12667                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12668                    Slog.w(TAG, msg);
12669                    throw new SecurityException(msg);
12670                }
12671                result = true;
12672            }
12673        } else if (componentProcessName == aInfo.packageName) {
12674            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12675        } else if ("system".equals(componentProcessName)) {
12676            result = true;
12677        }
12678        if (DEBUG_MU) {
12679            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12680                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12681        }
12682        return result;
12683    }
12684
12685    public int bindService(IApplicationThread caller, IBinder token,
12686            Intent service, String resolvedType,
12687            IServiceConnection connection, int flags, int userId) {
12688        enforceNotIsolatedCaller("bindService");
12689        // Refuse possible leaked file descriptors
12690        if (service != null && service.hasFileDescriptors() == true) {
12691            throw new IllegalArgumentException("File descriptors passed in Intent");
12692        }
12693
12694        synchronized(this) {
12695            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12696                    connection, flags, userId);
12697        }
12698    }
12699
12700    public boolean unbindService(IServiceConnection connection) {
12701        synchronized (this) {
12702            return mServices.unbindServiceLocked(connection);
12703        }
12704    }
12705
12706    public void publishService(IBinder token, Intent intent, IBinder service) {
12707        // Refuse possible leaked file descriptors
12708        if (intent != null && intent.hasFileDescriptors() == true) {
12709            throw new IllegalArgumentException("File descriptors passed in Intent");
12710        }
12711
12712        synchronized(this) {
12713            if (!(token instanceof ServiceRecord)) {
12714                throw new IllegalArgumentException("Invalid service token");
12715            }
12716            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12717        }
12718    }
12719
12720    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12721        // Refuse possible leaked file descriptors
12722        if (intent != null && intent.hasFileDescriptors() == true) {
12723            throw new IllegalArgumentException("File descriptors passed in Intent");
12724        }
12725
12726        synchronized(this) {
12727            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12728        }
12729    }
12730
12731    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12732        synchronized(this) {
12733            if (!(token instanceof ServiceRecord)) {
12734                throw new IllegalArgumentException("Invalid service token");
12735            }
12736            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12737        }
12738    }
12739
12740    // =========================================================
12741    // BACKUP AND RESTORE
12742    // =========================================================
12743
12744    // Cause the target app to be launched if necessary and its backup agent
12745    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12746    // activity manager to announce its creation.
12747    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12748        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12749        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12750
12751        synchronized(this) {
12752            // !!! TODO: currently no check here that we're already bound
12753            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12754            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12755            synchronized (stats) {
12756                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12757            }
12758
12759            // Backup agent is now in use, its package can't be stopped.
12760            try {
12761                AppGlobals.getPackageManager().setPackageStoppedState(
12762                        app.packageName, false, UserHandle.getUserId(app.uid));
12763            } catch (RemoteException e) {
12764            } catch (IllegalArgumentException e) {
12765                Slog.w(TAG, "Failed trying to unstop package "
12766                        + app.packageName + ": " + e);
12767            }
12768
12769            BackupRecord r = new BackupRecord(ss, app, backupMode);
12770            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12771                    ? new ComponentName(app.packageName, app.backupAgentName)
12772                    : new ComponentName("android", "FullBackupAgent");
12773            // startProcessLocked() returns existing proc's record if it's already running
12774            ProcessRecord proc = startProcessLocked(app.processName, app,
12775                    false, 0, "backup", hostingName, false, false, false);
12776            if (proc == null) {
12777                Slog.e(TAG, "Unable to start backup agent process " + r);
12778                return false;
12779            }
12780
12781            r.app = proc;
12782            mBackupTarget = r;
12783            mBackupAppName = app.packageName;
12784
12785            // Try not to kill the process during backup
12786            updateOomAdjLocked(proc);
12787
12788            // If the process is already attached, schedule the creation of the backup agent now.
12789            // If it is not yet live, this will be done when it attaches to the framework.
12790            if (proc.thread != null) {
12791                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12792                try {
12793                    proc.thread.scheduleCreateBackupAgent(app,
12794                            compatibilityInfoForPackageLocked(app), backupMode);
12795                } catch (RemoteException e) {
12796                    // Will time out on the backup manager side
12797                }
12798            } else {
12799                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12800            }
12801            // Invariants: at this point, the target app process exists and the application
12802            // is either already running or in the process of coming up.  mBackupTarget and
12803            // mBackupAppName describe the app, so that when it binds back to the AM we
12804            // know that it's scheduled for a backup-agent operation.
12805        }
12806
12807        return true;
12808    }
12809
12810    @Override
12811    public void clearPendingBackup() {
12812        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12813        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12814
12815        synchronized (this) {
12816            mBackupTarget = null;
12817            mBackupAppName = null;
12818        }
12819    }
12820
12821    // A backup agent has just come up
12822    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12823        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12824                + " = " + agent);
12825
12826        synchronized(this) {
12827            if (!agentPackageName.equals(mBackupAppName)) {
12828                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12829                return;
12830            }
12831        }
12832
12833        long oldIdent = Binder.clearCallingIdentity();
12834        try {
12835            IBackupManager bm = IBackupManager.Stub.asInterface(
12836                    ServiceManager.getService(Context.BACKUP_SERVICE));
12837            bm.agentConnected(agentPackageName, agent);
12838        } catch (RemoteException e) {
12839            // can't happen; the backup manager service is local
12840        } catch (Exception e) {
12841            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12842            e.printStackTrace();
12843        } finally {
12844            Binder.restoreCallingIdentity(oldIdent);
12845        }
12846    }
12847
12848    // done with this agent
12849    public void unbindBackupAgent(ApplicationInfo appInfo) {
12850        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12851        if (appInfo == null) {
12852            Slog.w(TAG, "unbind backup agent for null app");
12853            return;
12854        }
12855
12856        synchronized(this) {
12857            try {
12858                if (mBackupAppName == null) {
12859                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12860                    return;
12861                }
12862
12863                if (!mBackupAppName.equals(appInfo.packageName)) {
12864                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12865                    return;
12866                }
12867
12868                // Not backing this app up any more; reset its OOM adjustment
12869                final ProcessRecord proc = mBackupTarget.app;
12870                updateOomAdjLocked(proc);
12871
12872                // If the app crashed during backup, 'thread' will be null here
12873                if (proc.thread != null) {
12874                    try {
12875                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12876                                compatibilityInfoForPackageLocked(appInfo));
12877                    } catch (Exception e) {
12878                        Slog.e(TAG, "Exception when unbinding backup agent:");
12879                        e.printStackTrace();
12880                    }
12881                }
12882            } finally {
12883                mBackupTarget = null;
12884                mBackupAppName = null;
12885            }
12886        }
12887    }
12888    // =========================================================
12889    // BROADCASTS
12890    // =========================================================
12891
12892    private final List getStickiesLocked(String action, IntentFilter filter,
12893            List cur, int userId) {
12894        final ContentResolver resolver = mContext.getContentResolver();
12895        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12896        if (stickies == null) {
12897            return cur;
12898        }
12899        final ArrayList<Intent> list = stickies.get(action);
12900        if (list == null) {
12901            return cur;
12902        }
12903        int N = list.size();
12904        for (int i=0; i<N; i++) {
12905            Intent intent = list.get(i);
12906            if (filter.match(resolver, intent, true, TAG) >= 0) {
12907                if (cur == null) {
12908                    cur = new ArrayList<Intent>();
12909                }
12910                cur.add(intent);
12911            }
12912        }
12913        return cur;
12914    }
12915
12916    boolean isPendingBroadcastProcessLocked(int pid) {
12917        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12918                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12919    }
12920
12921    void skipPendingBroadcastLocked(int pid) {
12922            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12923            for (BroadcastQueue queue : mBroadcastQueues) {
12924                queue.skipPendingBroadcastLocked(pid);
12925            }
12926    }
12927
12928    // The app just attached; send any pending broadcasts that it should receive
12929    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12930        boolean didSomething = false;
12931        for (BroadcastQueue queue : mBroadcastQueues) {
12932            didSomething |= queue.sendPendingBroadcastsLocked(app);
12933        }
12934        return didSomething;
12935    }
12936
12937    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12938            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12939        enforceNotIsolatedCaller("registerReceiver");
12940        int callingUid;
12941        int callingPid;
12942        synchronized(this) {
12943            ProcessRecord callerApp = null;
12944            if (caller != null) {
12945                callerApp = getRecordForAppLocked(caller);
12946                if (callerApp == null) {
12947                    throw new SecurityException(
12948                            "Unable to find app for caller " + caller
12949                            + " (pid=" + Binder.getCallingPid()
12950                            + ") when registering receiver " + receiver);
12951                }
12952                if (callerApp.info.uid != Process.SYSTEM_UID &&
12953                        !callerApp.pkgList.containsKey(callerPackage) &&
12954                        !"android".equals(callerPackage)) {
12955                    throw new SecurityException("Given caller package " + callerPackage
12956                            + " is not running in process " + callerApp);
12957                }
12958                callingUid = callerApp.info.uid;
12959                callingPid = callerApp.pid;
12960            } else {
12961                callerPackage = null;
12962                callingUid = Binder.getCallingUid();
12963                callingPid = Binder.getCallingPid();
12964            }
12965
12966            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12967                    true, true, "registerReceiver", callerPackage);
12968
12969            List allSticky = null;
12970
12971            // Look for any matching sticky broadcasts...
12972            Iterator actions = filter.actionsIterator();
12973            if (actions != null) {
12974                while (actions.hasNext()) {
12975                    String action = (String)actions.next();
12976                    allSticky = getStickiesLocked(action, filter, allSticky,
12977                            UserHandle.USER_ALL);
12978                    allSticky = getStickiesLocked(action, filter, allSticky,
12979                            UserHandle.getUserId(callingUid));
12980                }
12981            } else {
12982                allSticky = getStickiesLocked(null, filter, allSticky,
12983                        UserHandle.USER_ALL);
12984                allSticky = getStickiesLocked(null, filter, allSticky,
12985                        UserHandle.getUserId(callingUid));
12986            }
12987
12988            // The first sticky in the list is returned directly back to
12989            // the client.
12990            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12991
12992            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12993                    + ": " + sticky);
12994
12995            if (receiver == null) {
12996                return sticky;
12997            }
12998
12999            ReceiverList rl
13000                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13001            if (rl == null) {
13002                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13003                        userId, receiver);
13004                if (rl.app != null) {
13005                    rl.app.receivers.add(rl);
13006                } else {
13007                    try {
13008                        receiver.asBinder().linkToDeath(rl, 0);
13009                    } catch (RemoteException e) {
13010                        return sticky;
13011                    }
13012                    rl.linkedToDeath = true;
13013                }
13014                mRegisteredReceivers.put(receiver.asBinder(), rl);
13015            } else if (rl.uid != callingUid) {
13016                throw new IllegalArgumentException(
13017                        "Receiver requested to register for uid " + callingUid
13018                        + " was previously registered for uid " + rl.uid);
13019            } else if (rl.pid != callingPid) {
13020                throw new IllegalArgumentException(
13021                        "Receiver requested to register for pid " + callingPid
13022                        + " was previously registered for pid " + rl.pid);
13023            } else if (rl.userId != userId) {
13024                throw new IllegalArgumentException(
13025                        "Receiver requested to register for user " + userId
13026                        + " was previously registered for user " + rl.userId);
13027            }
13028            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13029                    permission, callingUid, userId);
13030            rl.add(bf);
13031            if (!bf.debugCheck()) {
13032                Slog.w(TAG, "==> For Dynamic broadast");
13033            }
13034            mReceiverResolver.addFilter(bf);
13035
13036            // Enqueue broadcasts for all existing stickies that match
13037            // this filter.
13038            if (allSticky != null) {
13039                ArrayList receivers = new ArrayList();
13040                receivers.add(bf);
13041
13042                int N = allSticky.size();
13043                for (int i=0; i<N; i++) {
13044                    Intent intent = (Intent)allSticky.get(i);
13045                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13046                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13047                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13048                            null, null, false, true, true, -1);
13049                    queue.enqueueParallelBroadcastLocked(r);
13050                    queue.scheduleBroadcastsLocked();
13051                }
13052            }
13053
13054            return sticky;
13055        }
13056    }
13057
13058    public void unregisterReceiver(IIntentReceiver receiver) {
13059        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13060
13061        final long origId = Binder.clearCallingIdentity();
13062        try {
13063            boolean doTrim = false;
13064
13065            synchronized(this) {
13066                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13067                if (rl != null) {
13068                    if (rl.curBroadcast != null) {
13069                        BroadcastRecord r = rl.curBroadcast;
13070                        final boolean doNext = finishReceiverLocked(
13071                                receiver.asBinder(), r.resultCode, r.resultData,
13072                                r.resultExtras, r.resultAbort);
13073                        if (doNext) {
13074                            doTrim = true;
13075                            r.queue.processNextBroadcast(false);
13076                        }
13077                    }
13078
13079                    if (rl.app != null) {
13080                        rl.app.receivers.remove(rl);
13081                    }
13082                    removeReceiverLocked(rl);
13083                    if (rl.linkedToDeath) {
13084                        rl.linkedToDeath = false;
13085                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13086                    }
13087                }
13088            }
13089
13090            // If we actually concluded any broadcasts, we might now be able
13091            // to trim the recipients' apps from our working set
13092            if (doTrim) {
13093                trimApplications();
13094                return;
13095            }
13096
13097        } finally {
13098            Binder.restoreCallingIdentity(origId);
13099        }
13100    }
13101
13102    void removeReceiverLocked(ReceiverList rl) {
13103        mRegisteredReceivers.remove(rl.receiver.asBinder());
13104        int N = rl.size();
13105        for (int i=0; i<N; i++) {
13106            mReceiverResolver.removeFilter(rl.get(i));
13107        }
13108    }
13109
13110    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13111        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13112            ProcessRecord r = mLruProcesses.get(i);
13113            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13114                try {
13115                    r.thread.dispatchPackageBroadcast(cmd, packages);
13116                } catch (RemoteException ex) {
13117                }
13118            }
13119        }
13120    }
13121
13122    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13123            int[] users) {
13124        List<ResolveInfo> receivers = null;
13125        try {
13126            HashSet<ComponentName> singleUserReceivers = null;
13127            boolean scannedFirstReceivers = false;
13128            for (int user : users) {
13129                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13130                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13131                if (user != 0 && newReceivers != null) {
13132                    // If this is not the primary user, we need to check for
13133                    // any receivers that should be filtered out.
13134                    for (int i=0; i<newReceivers.size(); i++) {
13135                        ResolveInfo ri = newReceivers.get(i);
13136                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13137                            newReceivers.remove(i);
13138                            i--;
13139                        }
13140                    }
13141                }
13142                if (newReceivers != null && newReceivers.size() == 0) {
13143                    newReceivers = null;
13144                }
13145                if (receivers == null) {
13146                    receivers = newReceivers;
13147                } else if (newReceivers != null) {
13148                    // We need to concatenate the additional receivers
13149                    // found with what we have do far.  This would be easy,
13150                    // but we also need to de-dup any receivers that are
13151                    // singleUser.
13152                    if (!scannedFirstReceivers) {
13153                        // Collect any single user receivers we had already retrieved.
13154                        scannedFirstReceivers = true;
13155                        for (int i=0; i<receivers.size(); i++) {
13156                            ResolveInfo ri = receivers.get(i);
13157                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13158                                ComponentName cn = new ComponentName(
13159                                        ri.activityInfo.packageName, ri.activityInfo.name);
13160                                if (singleUserReceivers == null) {
13161                                    singleUserReceivers = new HashSet<ComponentName>();
13162                                }
13163                                singleUserReceivers.add(cn);
13164                            }
13165                        }
13166                    }
13167                    // Add the new results to the existing results, tracking
13168                    // and de-dupping single user receivers.
13169                    for (int i=0; i<newReceivers.size(); i++) {
13170                        ResolveInfo ri = newReceivers.get(i);
13171                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13172                            ComponentName cn = new ComponentName(
13173                                    ri.activityInfo.packageName, ri.activityInfo.name);
13174                            if (singleUserReceivers == null) {
13175                                singleUserReceivers = new HashSet<ComponentName>();
13176                            }
13177                            if (!singleUserReceivers.contains(cn)) {
13178                                singleUserReceivers.add(cn);
13179                                receivers.add(ri);
13180                            }
13181                        } else {
13182                            receivers.add(ri);
13183                        }
13184                    }
13185                }
13186            }
13187        } catch (RemoteException ex) {
13188            // pm is in same process, this will never happen.
13189        }
13190        return receivers;
13191    }
13192
13193    private final int broadcastIntentLocked(ProcessRecord callerApp,
13194            String callerPackage, Intent intent, String resolvedType,
13195            IIntentReceiver resultTo, int resultCode, String resultData,
13196            Bundle map, String requiredPermission, int appOp,
13197            boolean ordered, boolean sticky, int callingPid, int callingUid,
13198            int userId) {
13199        intent = new Intent(intent);
13200
13201        // By default broadcasts do not go to stopped apps.
13202        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13203
13204        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13205            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13206            + " ordered=" + ordered + " userid=" + userId);
13207        if ((resultTo != null) && !ordered) {
13208            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13209        }
13210
13211        userId = handleIncomingUser(callingPid, callingUid, userId,
13212                true, false, "broadcast", callerPackage);
13213
13214        // Make sure that the user who is receiving this broadcast is started.
13215        // If not, we will just skip it.
13216        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13217            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13218                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13219                Slog.w(TAG, "Skipping broadcast of " + intent
13220                        + ": user " + userId + " is stopped");
13221                return ActivityManager.BROADCAST_SUCCESS;
13222            }
13223        }
13224
13225        /*
13226         * Prevent non-system code (defined here to be non-persistent
13227         * processes) from sending protected broadcasts.
13228         */
13229        int callingAppId = UserHandle.getAppId(callingUid);
13230        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13231            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13232            callingUid == 0) {
13233            // Always okay.
13234        } else if (callerApp == null || !callerApp.persistent) {
13235            try {
13236                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13237                        intent.getAction())) {
13238                    String msg = "Permission Denial: not allowed to send broadcast "
13239                            + intent.getAction() + " from pid="
13240                            + callingPid + ", uid=" + callingUid;
13241                    Slog.w(TAG, msg);
13242                    throw new SecurityException(msg);
13243                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13244                    // Special case for compatibility: we don't want apps to send this,
13245                    // but historically it has not been protected and apps may be using it
13246                    // to poke their own app widget.  So, instead of making it protected,
13247                    // just limit it to the caller.
13248                    if (callerApp == null) {
13249                        String msg = "Permission Denial: not allowed to send broadcast "
13250                                + intent.getAction() + " from unknown caller.";
13251                        Slog.w(TAG, msg);
13252                        throw new SecurityException(msg);
13253                    } else if (intent.getComponent() != null) {
13254                        // They are good enough to send to an explicit component...  verify
13255                        // it is being sent to the calling app.
13256                        if (!intent.getComponent().getPackageName().equals(
13257                                callerApp.info.packageName)) {
13258                            String msg = "Permission Denial: not allowed to send broadcast "
13259                                    + intent.getAction() + " to "
13260                                    + intent.getComponent().getPackageName() + " from "
13261                                    + callerApp.info.packageName;
13262                            Slog.w(TAG, msg);
13263                            throw new SecurityException(msg);
13264                        }
13265                    } else {
13266                        // Limit broadcast to their own package.
13267                        intent.setPackage(callerApp.info.packageName);
13268                    }
13269                }
13270            } catch (RemoteException e) {
13271                Slog.w(TAG, "Remote exception", e);
13272                return ActivityManager.BROADCAST_SUCCESS;
13273            }
13274        }
13275
13276        // Handle special intents: if this broadcast is from the package
13277        // manager about a package being removed, we need to remove all of
13278        // its activities from the history stack.
13279        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13280                intent.getAction());
13281        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13282                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13283                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13284                || uidRemoved) {
13285            if (checkComponentPermission(
13286                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13287                    callingPid, callingUid, -1, true)
13288                    == PackageManager.PERMISSION_GRANTED) {
13289                if (uidRemoved) {
13290                    final Bundle intentExtras = intent.getExtras();
13291                    final int uid = intentExtras != null
13292                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13293                    if (uid >= 0) {
13294                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13295                        synchronized (bs) {
13296                            bs.removeUidStatsLocked(uid);
13297                        }
13298                        mAppOpsService.uidRemoved(uid);
13299                    }
13300                } else {
13301                    // If resources are unavailable just force stop all
13302                    // those packages and flush the attribute cache as well.
13303                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13304                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13305                        if (list != null && (list.length > 0)) {
13306                            for (String pkg : list) {
13307                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13308                                        "storage unmount");
13309                            }
13310                            sendPackageBroadcastLocked(
13311                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13312                        }
13313                    } else {
13314                        Uri data = intent.getData();
13315                        String ssp;
13316                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13317                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13318                                    intent.getAction());
13319                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13320                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13321                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13322                                        false, userId, 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, 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, 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                mSystemThread.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            if (Process.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            } else {
15190                success = false;
15191                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
15192            }
15193        }
15194        if (app.setSchedGroup != app.curSchedGroup) {
15195            app.setSchedGroup = app.curSchedGroup;
15196            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15197                    "Setting process group of " + app.processName
15198                    + " to " + app.curSchedGroup);
15199            if (app.waitingToKill != null &&
15200                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15201                killUnneededProcessLocked(app, app.waitingToKill);
15202                success = false;
15203            } else {
15204                if (true) {
15205                    long oldId = Binder.clearCallingIdentity();
15206                    try {
15207                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15208                    } catch (Exception e) {
15209                        Slog.w(TAG, "Failed setting process group of " + app.pid
15210                                + " to " + app.curSchedGroup);
15211                        e.printStackTrace();
15212                    } finally {
15213                        Binder.restoreCallingIdentity(oldId);
15214                    }
15215                } else {
15216                    if (app.thread != null) {
15217                        try {
15218                            app.thread.setSchedulingGroup(app.curSchedGroup);
15219                        } catch (RemoteException e) {
15220                        }
15221                    }
15222                }
15223                Process.setSwappiness(app.pid,
15224                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15225            }
15226        }
15227        if (app.repProcState != app.curProcState) {
15228            app.repProcState = app.curProcState;
15229            if (!reportingProcessState && app.thread != null) {
15230                try {
15231                    if (false) {
15232                        //RuntimeException h = new RuntimeException("here");
15233                        Slog.i(TAG, "Sending new process state " + app.repProcState
15234                                + " to " + app /*, h*/);
15235                    }
15236                    app.thread.setProcessState(app.repProcState);
15237                } catch (RemoteException e) {
15238                }
15239            }
15240        }
15241        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15242                app.setProcState)) {
15243            app.lastStateTime = now;
15244            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15245                    mSleeping, now);
15246            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15247                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15248                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15249                    + (app.nextPssTime-now) + ": " + app);
15250        } else {
15251            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15252                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15253                requestPssLocked(app, app.setProcState);
15254                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15255                        mSleeping, now);
15256            } else if (false && DEBUG_PSS) {
15257                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15258            }
15259        }
15260        if (app.setProcState != app.curProcState) {
15261            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15262                    "Proc state change of " + app.processName
15263                    + " to " + app.curProcState);
15264            app.setProcState = app.curProcState;
15265            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15266                app.notCachedSinceIdle = false;
15267            }
15268            if (!doingAll) {
15269                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15270            } else {
15271                app.procStateChanged = true;
15272            }
15273        }
15274        return success;
15275    }
15276
15277    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15278        if (proc.thread != null && proc.baseProcessTracker != null) {
15279            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15280        }
15281    }
15282
15283    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15284            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15285        if (app.thread == null) {
15286            return false;
15287        }
15288
15289        final boolean wasKeeping = app.keeping;
15290
15291        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15292
15293        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15294                reportingProcessState, now);
15295    }
15296
15297    private final ActivityRecord resumedAppLocked() {
15298        return mStackSupervisor.resumedAppLocked();
15299    }
15300
15301    final boolean updateOomAdjLocked(ProcessRecord app) {
15302        return updateOomAdjLocked(app, false);
15303    }
15304
15305    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15306        final ActivityRecord TOP_ACT = resumedAppLocked();
15307        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15308        final boolean wasCached = app.cached;
15309
15310        mAdjSeq++;
15311
15312        // This is the desired cached adjusment we want to tell it to use.
15313        // If our app is currently cached, we know it, and that is it.  Otherwise,
15314        // we don't know it yet, and it needs to now be cached we will then
15315        // need to do a complete oom adj.
15316        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15317                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15318        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15319                SystemClock.uptimeMillis());
15320        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15321            // Changed to/from cached state, so apps after it in the LRU
15322            // list may also be changed.
15323            updateOomAdjLocked();
15324        }
15325        return success;
15326    }
15327
15328    final void updateOomAdjLocked() {
15329        final ActivityRecord TOP_ACT = resumedAppLocked();
15330        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15331        final long now = SystemClock.uptimeMillis();
15332        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15333        final int N = mLruProcesses.size();
15334
15335        if (false) {
15336            RuntimeException e = new RuntimeException();
15337            e.fillInStackTrace();
15338            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15339        }
15340
15341        mAdjSeq++;
15342        mNewNumServiceProcs = 0;
15343        mNewNumAServiceProcs = 0;
15344
15345        final int emptyProcessLimit;
15346        final int cachedProcessLimit;
15347        if (mProcessLimit <= 0) {
15348            emptyProcessLimit = cachedProcessLimit = 0;
15349        } else if (mProcessLimit == 1) {
15350            emptyProcessLimit = 1;
15351            cachedProcessLimit = 0;
15352        } else {
15353            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15354            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15355        }
15356
15357        // Let's determine how many processes we have running vs.
15358        // how many slots we have for background processes; we may want
15359        // to put multiple processes in a slot of there are enough of
15360        // them.
15361        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15362                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15363        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15364        if (numEmptyProcs > cachedProcessLimit) {
15365            // If there are more empty processes than our limit on cached
15366            // processes, then use the cached process limit for the factor.
15367            // This ensures that the really old empty processes get pushed
15368            // down to the bottom, so if we are running low on memory we will
15369            // have a better chance at keeping around more cached processes
15370            // instead of a gazillion empty processes.
15371            numEmptyProcs = cachedProcessLimit;
15372        }
15373        int emptyFactor = numEmptyProcs/numSlots;
15374        if (emptyFactor < 1) emptyFactor = 1;
15375        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15376        if (cachedFactor < 1) cachedFactor = 1;
15377        int stepCached = 0;
15378        int stepEmpty = 0;
15379        int numCached = 0;
15380        int numEmpty = 0;
15381        int numTrimming = 0;
15382
15383        mNumNonCachedProcs = 0;
15384        mNumCachedHiddenProcs = 0;
15385
15386        // First update the OOM adjustment for each of the
15387        // application processes based on their current state.
15388        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15389        int nextCachedAdj = curCachedAdj+1;
15390        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15391        int nextEmptyAdj = curEmptyAdj+2;
15392        for (int i=N-1; i>=0; i--) {
15393            ProcessRecord app = mLruProcesses.get(i);
15394            if (!app.killedByAm && app.thread != null) {
15395                app.procStateChanged = false;
15396                final boolean wasKeeping = app.keeping;
15397                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15398
15399                // If we haven't yet assigned the final cached adj
15400                // to the process, do that now.
15401                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15402                    switch (app.curProcState) {
15403                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15404                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15405                            // This process is a cached process holding activities...
15406                            // assign it the next cached value for that type, and then
15407                            // step that cached level.
15408                            app.curRawAdj = curCachedAdj;
15409                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15410                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15411                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15412                                    + ")");
15413                            if (curCachedAdj != nextCachedAdj) {
15414                                stepCached++;
15415                                if (stepCached >= cachedFactor) {
15416                                    stepCached = 0;
15417                                    curCachedAdj = nextCachedAdj;
15418                                    nextCachedAdj += 2;
15419                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15420                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15421                                    }
15422                                }
15423                            }
15424                            break;
15425                        default:
15426                            // For everything else, assign next empty cached process
15427                            // level and bump that up.  Note that this means that
15428                            // long-running services that have dropped down to the
15429                            // cached level will be treated as empty (since their process
15430                            // state is still as a service), which is what we want.
15431                            app.curRawAdj = curEmptyAdj;
15432                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15433                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15434                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15435                                    + ")");
15436                            if (curEmptyAdj != nextEmptyAdj) {
15437                                stepEmpty++;
15438                                if (stepEmpty >= emptyFactor) {
15439                                    stepEmpty = 0;
15440                                    curEmptyAdj = nextEmptyAdj;
15441                                    nextEmptyAdj += 2;
15442                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15443                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15444                                    }
15445                                }
15446                            }
15447                            break;
15448                    }
15449                }
15450
15451                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15452
15453                // Count the number of process types.
15454                switch (app.curProcState) {
15455                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15456                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15457                        mNumCachedHiddenProcs++;
15458                        numCached++;
15459                        if (numCached > cachedProcessLimit) {
15460                            killUnneededProcessLocked(app, "cached #" + numCached);
15461                        }
15462                        break;
15463                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15464                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15465                                && app.lastActivityTime < oldTime) {
15466                            killUnneededProcessLocked(app, "empty for "
15467                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15468                                    / 1000) + "s");
15469                        } else {
15470                            numEmpty++;
15471                            if (numEmpty > emptyProcessLimit) {
15472                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15473                            }
15474                        }
15475                        break;
15476                    default:
15477                        mNumNonCachedProcs++;
15478                        break;
15479                }
15480
15481                if (app.isolated && app.services.size() <= 0) {
15482                    // If this is an isolated process, and there are no
15483                    // services running in it, then the process is no longer
15484                    // needed.  We agressively kill these because we can by
15485                    // definition not re-use the same process again, and it is
15486                    // good to avoid having whatever code was running in them
15487                    // left sitting around after no longer needed.
15488                    killUnneededProcessLocked(app, "isolated not needed");
15489                }
15490
15491                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15492                        && !app.killedByAm) {
15493                    numTrimming++;
15494                }
15495            }
15496        }
15497
15498        mNumServiceProcs = mNewNumServiceProcs;
15499
15500        // Now determine the memory trimming level of background processes.
15501        // Unfortunately we need to start at the back of the list to do this
15502        // properly.  We only do this if the number of background apps we
15503        // are managing to keep around is less than half the maximum we desire;
15504        // if we are keeping a good number around, we'll let them use whatever
15505        // memory they want.
15506        final int numCachedAndEmpty = numCached + numEmpty;
15507        int memFactor;
15508        if (numCached <= ProcessList.TRIM_CACHED_APPS
15509                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15510            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15511                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15512            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15513                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15514            } else {
15515                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15516            }
15517        } else {
15518            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15519        }
15520        // We always allow the memory level to go up (better).  We only allow it to go
15521        // down if we are in a state where that is allowed, *and* the total number of processes
15522        // has gone down since last time.
15523        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15524                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15525                + " last=" + mLastNumProcesses);
15526        if (memFactor > mLastMemoryLevel) {
15527            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15528                memFactor = mLastMemoryLevel;
15529                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15530            }
15531        }
15532        mLastMemoryLevel = memFactor;
15533        mLastNumProcesses = mLruProcesses.size();
15534        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15535        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15536        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15537            if (mLowRamStartTime == 0) {
15538                mLowRamStartTime = now;
15539            }
15540            int step = 0;
15541            int fgTrimLevel;
15542            switch (memFactor) {
15543                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15544                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15545                    break;
15546                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15547                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15548                    break;
15549                default:
15550                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15551                    break;
15552            }
15553            int factor = numTrimming/3;
15554            int minFactor = 2;
15555            if (mHomeProcess != null) minFactor++;
15556            if (mPreviousProcess != null) minFactor++;
15557            if (factor < minFactor) factor = minFactor;
15558            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15559            for (int i=N-1; i>=0; i--) {
15560                ProcessRecord app = mLruProcesses.get(i);
15561                if (allChanged || app.procStateChanged) {
15562                    setProcessTrackerState(app, trackerMemFactor, now);
15563                    app.procStateChanged = false;
15564                }
15565                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15566                        && !app.killedByAm) {
15567                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15568                        try {
15569                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15570                                    "Trimming memory of " + app.processName
15571                                    + " to " + curLevel);
15572                            app.thread.scheduleTrimMemory(curLevel);
15573                        } catch (RemoteException e) {
15574                        }
15575                        if (false) {
15576                            // For now we won't do this; our memory trimming seems
15577                            // to be good enough at this point that destroying
15578                            // activities causes more harm than good.
15579                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15580                                    && app != mHomeProcess && app != mPreviousProcess) {
15581                                // Need to do this on its own message because the stack may not
15582                                // be in a consistent state at this point.
15583                                // For these apps we will also finish their activities
15584                                // to help them free memory.
15585                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15586                            }
15587                        }
15588                    }
15589                    app.trimMemoryLevel = curLevel;
15590                    step++;
15591                    if (step >= factor) {
15592                        step = 0;
15593                        switch (curLevel) {
15594                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15595                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15596                                break;
15597                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15598                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15599                                break;
15600                        }
15601                    }
15602                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15603                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15604                            && app.thread != null) {
15605                        try {
15606                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15607                                    "Trimming memory of heavy-weight " + app.processName
15608                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15609                            app.thread.scheduleTrimMemory(
15610                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15611                        } catch (RemoteException e) {
15612                        }
15613                    }
15614                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15615                } else {
15616                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15617                            || app.systemNoUi) && app.pendingUiClean) {
15618                        // If this application is now in the background and it
15619                        // had done UI, then give it the special trim level to
15620                        // have it free UI resources.
15621                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15622                        if (app.trimMemoryLevel < level && app.thread != null) {
15623                            try {
15624                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15625                                        "Trimming memory of bg-ui " + app.processName
15626                                        + " to " + level);
15627                                app.thread.scheduleTrimMemory(level);
15628                            } catch (RemoteException e) {
15629                            }
15630                        }
15631                        app.pendingUiClean = false;
15632                    }
15633                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15634                        try {
15635                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15636                                    "Trimming memory of fg " + app.processName
15637                                    + " to " + fgTrimLevel);
15638                            app.thread.scheduleTrimMemory(fgTrimLevel);
15639                        } catch (RemoteException e) {
15640                        }
15641                    }
15642                    app.trimMemoryLevel = fgTrimLevel;
15643                }
15644            }
15645        } else {
15646            if (mLowRamStartTime != 0) {
15647                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15648                mLowRamStartTime = 0;
15649            }
15650            for (int i=N-1; i>=0; i--) {
15651                ProcessRecord app = mLruProcesses.get(i);
15652                if (allChanged || app.procStateChanged) {
15653                    setProcessTrackerState(app, trackerMemFactor, now);
15654                    app.procStateChanged = false;
15655                }
15656                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15657                        || app.systemNoUi) && app.pendingUiClean) {
15658                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15659                            && app.thread != null) {
15660                        try {
15661                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15662                                    "Trimming memory of ui hidden " + app.processName
15663                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15664                            app.thread.scheduleTrimMemory(
15665                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15666                        } catch (RemoteException e) {
15667                        }
15668                    }
15669                    app.pendingUiClean = false;
15670                }
15671                app.trimMemoryLevel = 0;
15672            }
15673        }
15674
15675        if (mAlwaysFinishActivities) {
15676            // Need to do this on its own message because the stack may not
15677            // be in a consistent state at this point.
15678            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15679        }
15680
15681        if (allChanged) {
15682            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15683        }
15684
15685        if (mProcessStats.shouldWriteNowLocked(now)) {
15686            mHandler.post(new Runnable() {
15687                @Override public void run() {
15688                    synchronized (ActivityManagerService.this) {
15689                        mProcessStats.writeStateAsyncLocked();
15690                    }
15691                }
15692            });
15693        }
15694
15695        if (DEBUG_OOM_ADJ) {
15696            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15697        }
15698    }
15699
15700    final void trimApplications() {
15701        synchronized (this) {
15702            int i;
15703
15704            // First remove any unused application processes whose package
15705            // has been removed.
15706            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15707                final ProcessRecord app = mRemovedProcesses.get(i);
15708                if (app.activities.size() == 0
15709                        && app.curReceiver == null && app.services.size() == 0) {
15710                    Slog.i(
15711                        TAG, "Exiting empty application process "
15712                        + app.processName + " ("
15713                        + (app.thread != null ? app.thread.asBinder() : null)
15714                        + ")\n");
15715                    if (app.pid > 0 && app.pid != MY_PID) {
15716                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15717                                app.processName, app.setAdj, "empty");
15718                        app.killedByAm = true;
15719                        Process.killProcessQuiet(app.pid);
15720                    } else {
15721                        try {
15722                            app.thread.scheduleExit();
15723                        } catch (Exception e) {
15724                            // Ignore exceptions.
15725                        }
15726                    }
15727                    cleanUpApplicationRecordLocked(app, false, true, -1);
15728                    mRemovedProcesses.remove(i);
15729
15730                    if (app.persistent) {
15731                        if (app.persistent) {
15732                            addAppLocked(app.info, false);
15733                        }
15734                    }
15735                }
15736            }
15737
15738            // Now update the oom adj for all processes.
15739            updateOomAdjLocked();
15740        }
15741    }
15742
15743    /** This method sends the specified signal to each of the persistent apps */
15744    public void signalPersistentProcesses(int sig) throws RemoteException {
15745        if (sig != Process.SIGNAL_USR1) {
15746            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15747        }
15748
15749        synchronized (this) {
15750            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15751                    != PackageManager.PERMISSION_GRANTED) {
15752                throw new SecurityException("Requires permission "
15753                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15754            }
15755
15756            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15757                ProcessRecord r = mLruProcesses.get(i);
15758                if (r.thread != null && r.persistent) {
15759                    Process.sendSignal(r.pid, sig);
15760                }
15761            }
15762        }
15763    }
15764
15765    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15766        if (proc == null || proc == mProfileProc) {
15767            proc = mProfileProc;
15768            path = mProfileFile;
15769            profileType = mProfileType;
15770            clearProfilerLocked();
15771        }
15772        if (proc == null) {
15773            return;
15774        }
15775        try {
15776            proc.thread.profilerControl(false, path, null, profileType);
15777        } catch (RemoteException e) {
15778            throw new IllegalStateException("Process disappeared");
15779        }
15780    }
15781
15782    private void clearProfilerLocked() {
15783        if (mProfileFd != null) {
15784            try {
15785                mProfileFd.close();
15786            } catch (IOException e) {
15787            }
15788        }
15789        mProfileApp = null;
15790        mProfileProc = null;
15791        mProfileFile = null;
15792        mProfileType = 0;
15793        mAutoStopProfiler = false;
15794    }
15795
15796    public boolean profileControl(String process, int userId, boolean start,
15797            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15798
15799        try {
15800            synchronized (this) {
15801                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15802                // its own permission.
15803                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15804                        != PackageManager.PERMISSION_GRANTED) {
15805                    throw new SecurityException("Requires permission "
15806                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15807                }
15808
15809                if (start && fd == null) {
15810                    throw new IllegalArgumentException("null fd");
15811                }
15812
15813                ProcessRecord proc = null;
15814                if (process != null) {
15815                    proc = findProcessLocked(process, userId, "profileControl");
15816                }
15817
15818                if (start && (proc == null || proc.thread == null)) {
15819                    throw new IllegalArgumentException("Unknown process: " + process);
15820                }
15821
15822                if (start) {
15823                    stopProfilerLocked(null, null, 0);
15824                    setProfileApp(proc.info, proc.processName, path, fd, false);
15825                    mProfileProc = proc;
15826                    mProfileType = profileType;
15827                    try {
15828                        fd = fd.dup();
15829                    } catch (IOException e) {
15830                        fd = null;
15831                    }
15832                    proc.thread.profilerControl(start, path, fd, profileType);
15833                    fd = null;
15834                    mProfileFd = null;
15835                } else {
15836                    stopProfilerLocked(proc, path, profileType);
15837                    if (fd != null) {
15838                        try {
15839                            fd.close();
15840                        } catch (IOException e) {
15841                        }
15842                    }
15843                }
15844
15845                return true;
15846            }
15847        } catch (RemoteException e) {
15848            throw new IllegalStateException("Process disappeared");
15849        } finally {
15850            if (fd != null) {
15851                try {
15852                    fd.close();
15853                } catch (IOException e) {
15854                }
15855            }
15856        }
15857    }
15858
15859    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15860        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15861                userId, true, true, callName, null);
15862        ProcessRecord proc = null;
15863        try {
15864            int pid = Integer.parseInt(process);
15865            synchronized (mPidsSelfLocked) {
15866                proc = mPidsSelfLocked.get(pid);
15867            }
15868        } catch (NumberFormatException e) {
15869        }
15870
15871        if (proc == null) {
15872            ArrayMap<String, SparseArray<ProcessRecord>> all
15873                    = mProcessNames.getMap();
15874            SparseArray<ProcessRecord> procs = all.get(process);
15875            if (procs != null && procs.size() > 0) {
15876                proc = procs.valueAt(0);
15877                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15878                    for (int i=1; i<procs.size(); i++) {
15879                        ProcessRecord thisProc = procs.valueAt(i);
15880                        if (thisProc.userId == userId) {
15881                            proc = thisProc;
15882                            break;
15883                        }
15884                    }
15885                }
15886            }
15887        }
15888
15889        return proc;
15890    }
15891
15892    public boolean dumpHeap(String process, int userId, boolean managed,
15893            String path, ParcelFileDescriptor fd) throws RemoteException {
15894
15895        try {
15896            synchronized (this) {
15897                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15898                // its own permission (same as profileControl).
15899                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15900                        != PackageManager.PERMISSION_GRANTED) {
15901                    throw new SecurityException("Requires permission "
15902                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15903                }
15904
15905                if (fd == null) {
15906                    throw new IllegalArgumentException("null fd");
15907                }
15908
15909                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15910                if (proc == null || proc.thread == null) {
15911                    throw new IllegalArgumentException("Unknown process: " + process);
15912                }
15913
15914                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15915                if (!isDebuggable) {
15916                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15917                        throw new SecurityException("Process not debuggable: " + proc);
15918                    }
15919                }
15920
15921                proc.thread.dumpHeap(managed, path, fd);
15922                fd = null;
15923                return true;
15924            }
15925        } catch (RemoteException e) {
15926            throw new IllegalStateException("Process disappeared");
15927        } finally {
15928            if (fd != null) {
15929                try {
15930                    fd.close();
15931                } catch (IOException e) {
15932                }
15933            }
15934        }
15935    }
15936
15937    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15938    public void monitor() {
15939        synchronized (this) { }
15940    }
15941
15942    void onCoreSettingsChange(Bundle settings) {
15943        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15944            ProcessRecord processRecord = mLruProcesses.get(i);
15945            try {
15946                if (processRecord.thread != null) {
15947                    processRecord.thread.setCoreSettings(settings);
15948                }
15949            } catch (RemoteException re) {
15950                /* ignore */
15951            }
15952        }
15953    }
15954
15955    // Multi-user methods
15956
15957    @Override
15958    public boolean switchUser(final int userId) {
15959        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15960                != PackageManager.PERMISSION_GRANTED) {
15961            String msg = "Permission Denial: switchUser() from pid="
15962                    + Binder.getCallingPid()
15963                    + ", uid=" + Binder.getCallingUid()
15964                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15965            Slog.w(TAG, msg);
15966            throw new SecurityException(msg);
15967        }
15968
15969        final long ident = Binder.clearCallingIdentity();
15970        try {
15971            synchronized (this) {
15972                final int oldUserId = mCurrentUserId;
15973                if (oldUserId == userId) {
15974                    return true;
15975                }
15976
15977                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15978                if (userInfo == null) {
15979                    Slog.w(TAG, "No user info for user #" + userId);
15980                    return false;
15981                }
15982
15983                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15984                        R.anim.screen_user_enter);
15985
15986                boolean needStart = false;
15987
15988                // If the user we are switching to is not currently started, then
15989                // we need to start it now.
15990                if (mStartedUsers.get(userId) == null) {
15991                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15992                    updateStartedUserArrayLocked();
15993                    needStart = true;
15994                }
15995
15996                mCurrentUserId = userId;
15997                final Integer userIdInt = Integer.valueOf(userId);
15998                mUserLru.remove(userIdInt);
15999                mUserLru.add(userIdInt);
16000
16001                mWindowManager.setCurrentUser(userId);
16002
16003                // Once the internal notion of the active user has switched, we lock the device
16004                // with the option to show the user switcher on the keyguard.
16005                mWindowManager.lockNow(null);
16006
16007                final UserStartedState uss = mStartedUsers.get(userId);
16008
16009                // Make sure user is in the started state.  If it is currently
16010                // stopping, we need to knock that off.
16011                if (uss.mState == UserStartedState.STATE_STOPPING) {
16012                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16013                    // so we can just fairly silently bring the user back from
16014                    // the almost-dead.
16015                    uss.mState = UserStartedState.STATE_RUNNING;
16016                    updateStartedUserArrayLocked();
16017                    needStart = true;
16018                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16019                    // This means ACTION_SHUTDOWN has been sent, so we will
16020                    // need to treat this as a new boot of the user.
16021                    uss.mState = UserStartedState.STATE_BOOTING;
16022                    updateStartedUserArrayLocked();
16023                    needStart = true;
16024                }
16025
16026                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16027                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16028                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16029                        oldUserId, userId, uss));
16030                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16031                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16032                if (needStart) {
16033                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16034                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16035                            | Intent.FLAG_RECEIVER_FOREGROUND);
16036                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16037                    broadcastIntentLocked(null, null, intent,
16038                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16039                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16040                }
16041
16042                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16043                    if (userId != 0) {
16044                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16045                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16046                        broadcastIntentLocked(null, null, intent, null,
16047                                new IIntentReceiver.Stub() {
16048                                    public void performReceive(Intent intent, int resultCode,
16049                                            String data, Bundle extras, boolean ordered,
16050                                            boolean sticky, int sendingUser) {
16051                                        userInitialized(uss, userId);
16052                                    }
16053                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16054                                true, false, MY_PID, Process.SYSTEM_UID,
16055                                userId);
16056                        uss.initializing = true;
16057                    } else {
16058                        getUserManagerLocked().makeInitialized(userInfo.id);
16059                    }
16060                }
16061
16062                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16063                if (homeInFront) {
16064                    startHomeActivityLocked(userId);
16065                } else {
16066                    mStackSupervisor.resumeTopActivitiesLocked();
16067                }
16068
16069                EventLogTags.writeAmSwitchUser(userId);
16070                getUserManagerLocked().userForeground(userId);
16071                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16072                if (needStart) {
16073                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16074                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16075                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16076                    broadcastIntentLocked(null, null, intent,
16077                            null, new IIntentReceiver.Stub() {
16078                                @Override
16079                                public void performReceive(Intent intent, int resultCode, String data,
16080                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16081                                        throws RemoteException {
16082                                }
16083                            }, 0, null, null,
16084                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16085                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16086                }
16087            }
16088        } finally {
16089            Binder.restoreCallingIdentity(ident);
16090        }
16091
16092        return true;
16093    }
16094
16095    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16096        long ident = Binder.clearCallingIdentity();
16097        try {
16098            Intent intent;
16099            if (oldUserId >= 0) {
16100                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16101                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16102                        | Intent.FLAG_RECEIVER_FOREGROUND);
16103                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16104                broadcastIntentLocked(null, null, intent,
16105                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16106                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16107            }
16108            if (newUserId >= 0) {
16109                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16110                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16111                        | Intent.FLAG_RECEIVER_FOREGROUND);
16112                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16113                broadcastIntentLocked(null, null, intent,
16114                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16115                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16116                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16117                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16118                        | Intent.FLAG_RECEIVER_FOREGROUND);
16119                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16120                broadcastIntentLocked(null, null, intent,
16121                        null, null, 0, null, null,
16122                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16123                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16124            }
16125        } finally {
16126            Binder.restoreCallingIdentity(ident);
16127        }
16128    }
16129
16130    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16131            final int newUserId) {
16132        final int N = mUserSwitchObservers.beginBroadcast();
16133        if (N > 0) {
16134            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16135                int mCount = 0;
16136                @Override
16137                public void sendResult(Bundle data) throws RemoteException {
16138                    synchronized (ActivityManagerService.this) {
16139                        if (mCurUserSwitchCallback == this) {
16140                            mCount++;
16141                            if (mCount == N) {
16142                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16143                            }
16144                        }
16145                    }
16146                }
16147            };
16148            synchronized (this) {
16149                uss.switching = true;
16150                mCurUserSwitchCallback = callback;
16151            }
16152            for (int i=0; i<N; i++) {
16153                try {
16154                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16155                            newUserId, callback);
16156                } catch (RemoteException e) {
16157                }
16158            }
16159        } else {
16160            synchronized (this) {
16161                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16162            }
16163        }
16164        mUserSwitchObservers.finishBroadcast();
16165    }
16166
16167    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16168        synchronized (this) {
16169            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16170            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16171        }
16172    }
16173
16174    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16175        mCurUserSwitchCallback = null;
16176        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16177        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16178                oldUserId, newUserId, uss));
16179    }
16180
16181    void userInitialized(UserStartedState uss, int newUserId) {
16182        completeSwitchAndInitalize(uss, newUserId, true, false);
16183    }
16184
16185    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16186        completeSwitchAndInitalize(uss, newUserId, false, true);
16187    }
16188
16189    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16190            boolean clearInitializing, boolean clearSwitching) {
16191        boolean unfrozen = false;
16192        synchronized (this) {
16193            if (clearInitializing) {
16194                uss.initializing = false;
16195                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16196            }
16197            if (clearSwitching) {
16198                uss.switching = false;
16199            }
16200            if (!uss.switching && !uss.initializing) {
16201                mWindowManager.stopFreezingScreen();
16202                unfrozen = true;
16203            }
16204        }
16205        if (unfrozen) {
16206            final int N = mUserSwitchObservers.beginBroadcast();
16207            for (int i=0; i<N; i++) {
16208                try {
16209                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16210                } catch (RemoteException e) {
16211                }
16212            }
16213            mUserSwitchObservers.finishBroadcast();
16214        }
16215    }
16216
16217    void finishUserSwitch(UserStartedState uss) {
16218        synchronized (this) {
16219            if (uss.mState == UserStartedState.STATE_BOOTING
16220                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16221                uss.mState = UserStartedState.STATE_RUNNING;
16222                final int userId = uss.mHandle.getIdentifier();
16223                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16224                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16225                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16226                broadcastIntentLocked(null, null, intent,
16227                        null, null, 0, null, null,
16228                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16229                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16230            }
16231            int num = mUserLru.size();
16232            int i = 0;
16233            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16234                Integer oldUserId = mUserLru.get(i);
16235                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16236                if (oldUss == null) {
16237                    // Shouldn't happen, but be sane if it does.
16238                    mUserLru.remove(i);
16239                    num--;
16240                    continue;
16241                }
16242                if (oldUss.mState == UserStartedState.STATE_STOPPING
16243                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16244                    // This user is already stopping, doesn't count.
16245                    num--;
16246                    i++;
16247                    continue;
16248                }
16249                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16250                    // Owner and current can't be stopped, but count as running.
16251                    i++;
16252                    continue;
16253                }
16254                // This is a user to be stopped.
16255                stopUserLocked(oldUserId, null);
16256                num--;
16257                i++;
16258            }
16259        }
16260    }
16261
16262    @Override
16263    public int stopUser(final int userId, final IStopUserCallback callback) {
16264        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16265                != PackageManager.PERMISSION_GRANTED) {
16266            String msg = "Permission Denial: switchUser() from pid="
16267                    + Binder.getCallingPid()
16268                    + ", uid=" + Binder.getCallingUid()
16269                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16270            Slog.w(TAG, msg);
16271            throw new SecurityException(msg);
16272        }
16273        if (userId <= 0) {
16274            throw new IllegalArgumentException("Can't stop primary user " + userId);
16275        }
16276        synchronized (this) {
16277            return stopUserLocked(userId, callback);
16278        }
16279    }
16280
16281    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16282        if (mCurrentUserId == userId) {
16283            return ActivityManager.USER_OP_IS_CURRENT;
16284        }
16285
16286        final UserStartedState uss = mStartedUsers.get(userId);
16287        if (uss == null) {
16288            // User is not started, nothing to do...  but we do need to
16289            // callback if requested.
16290            if (callback != null) {
16291                mHandler.post(new Runnable() {
16292                    @Override
16293                    public void run() {
16294                        try {
16295                            callback.userStopped(userId);
16296                        } catch (RemoteException e) {
16297                        }
16298                    }
16299                });
16300            }
16301            return ActivityManager.USER_OP_SUCCESS;
16302        }
16303
16304        if (callback != null) {
16305            uss.mStopCallbacks.add(callback);
16306        }
16307
16308        if (uss.mState != UserStartedState.STATE_STOPPING
16309                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16310            uss.mState = UserStartedState.STATE_STOPPING;
16311            updateStartedUserArrayLocked();
16312
16313            long ident = Binder.clearCallingIdentity();
16314            try {
16315                // We are going to broadcast ACTION_USER_STOPPING and then
16316                // once that is done send a final ACTION_SHUTDOWN and then
16317                // stop the user.
16318                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16319                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16320                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16321                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16322                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16323                // This is the result receiver for the final shutdown broadcast.
16324                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16325                    @Override
16326                    public void performReceive(Intent intent, int resultCode, String data,
16327                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16328                        finishUserStop(uss);
16329                    }
16330                };
16331                // This is the result receiver for the initial stopping broadcast.
16332                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16333                    @Override
16334                    public void performReceive(Intent intent, int resultCode, String data,
16335                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16336                        // On to the next.
16337                        synchronized (ActivityManagerService.this) {
16338                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16339                                // Whoops, we are being started back up.  Abort, abort!
16340                                return;
16341                            }
16342                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16343                        }
16344                        broadcastIntentLocked(null, null, shutdownIntent,
16345                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16346                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16347                    }
16348                };
16349                // Kick things off.
16350                broadcastIntentLocked(null, null, stoppingIntent,
16351                        null, stoppingReceiver, 0, null, null,
16352                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16353                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16354            } finally {
16355                Binder.restoreCallingIdentity(ident);
16356            }
16357        }
16358
16359        return ActivityManager.USER_OP_SUCCESS;
16360    }
16361
16362    void finishUserStop(UserStartedState uss) {
16363        final int userId = uss.mHandle.getIdentifier();
16364        boolean stopped;
16365        ArrayList<IStopUserCallback> callbacks;
16366        synchronized (this) {
16367            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16368            if (mStartedUsers.get(userId) != uss) {
16369                stopped = false;
16370            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16371                stopped = false;
16372            } else {
16373                stopped = true;
16374                // User can no longer run.
16375                mStartedUsers.remove(userId);
16376                mUserLru.remove(Integer.valueOf(userId));
16377                updateStartedUserArrayLocked();
16378
16379                // Clean up all state and processes associated with the user.
16380                // Kill all the processes for the user.
16381                forceStopUserLocked(userId, "finish user");
16382            }
16383        }
16384
16385        for (int i=0; i<callbacks.size(); i++) {
16386            try {
16387                if (stopped) callbacks.get(i).userStopped(userId);
16388                else callbacks.get(i).userStopAborted(userId);
16389            } catch (RemoteException e) {
16390            }
16391        }
16392
16393        mStackSupervisor.removeUserLocked(userId);
16394    }
16395
16396    @Override
16397    public UserInfo getCurrentUser() {
16398        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16399                != PackageManager.PERMISSION_GRANTED) && (
16400                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16401                != PackageManager.PERMISSION_GRANTED)) {
16402            String msg = "Permission Denial: getCurrentUser() from pid="
16403                    + Binder.getCallingPid()
16404                    + ", uid=" + Binder.getCallingUid()
16405                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16406            Slog.w(TAG, msg);
16407            throw new SecurityException(msg);
16408        }
16409        synchronized (this) {
16410            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16411        }
16412    }
16413
16414    int getCurrentUserIdLocked() {
16415        return mCurrentUserId;
16416    }
16417
16418    @Override
16419    public boolean isUserRunning(int userId, boolean orStopped) {
16420        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16421                != PackageManager.PERMISSION_GRANTED) {
16422            String msg = "Permission Denial: isUserRunning() from pid="
16423                    + Binder.getCallingPid()
16424                    + ", uid=" + Binder.getCallingUid()
16425                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16426            Slog.w(TAG, msg);
16427            throw new SecurityException(msg);
16428        }
16429        synchronized (this) {
16430            return isUserRunningLocked(userId, orStopped);
16431        }
16432    }
16433
16434    boolean isUserRunningLocked(int userId, boolean orStopped) {
16435        UserStartedState state = mStartedUsers.get(userId);
16436        if (state == null) {
16437            return false;
16438        }
16439        if (orStopped) {
16440            return true;
16441        }
16442        return state.mState != UserStartedState.STATE_STOPPING
16443                && state.mState != UserStartedState.STATE_SHUTDOWN;
16444    }
16445
16446    @Override
16447    public int[] getRunningUserIds() {
16448        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16449                != PackageManager.PERMISSION_GRANTED) {
16450            String msg = "Permission Denial: isUserRunning() from pid="
16451                    + Binder.getCallingPid()
16452                    + ", uid=" + Binder.getCallingUid()
16453                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16454            Slog.w(TAG, msg);
16455            throw new SecurityException(msg);
16456        }
16457        synchronized (this) {
16458            return mStartedUserArray;
16459        }
16460    }
16461
16462    private void updateStartedUserArrayLocked() {
16463        int num = 0;
16464        for (int i=0; i<mStartedUsers.size();  i++) {
16465            UserStartedState uss = mStartedUsers.valueAt(i);
16466            // This list does not include stopping users.
16467            if (uss.mState != UserStartedState.STATE_STOPPING
16468                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16469                num++;
16470            }
16471        }
16472        mStartedUserArray = new int[num];
16473        num = 0;
16474        for (int i=0; i<mStartedUsers.size();  i++) {
16475            UserStartedState uss = mStartedUsers.valueAt(i);
16476            if (uss.mState != UserStartedState.STATE_STOPPING
16477                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16478                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16479                num++;
16480            }
16481        }
16482    }
16483
16484    @Override
16485    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16486        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16487                != PackageManager.PERMISSION_GRANTED) {
16488            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16489                    + Binder.getCallingPid()
16490                    + ", uid=" + Binder.getCallingUid()
16491                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16492            Slog.w(TAG, msg);
16493            throw new SecurityException(msg);
16494        }
16495
16496        mUserSwitchObservers.register(observer);
16497    }
16498
16499    @Override
16500    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16501        mUserSwitchObservers.unregister(observer);
16502    }
16503
16504    private boolean userExists(int userId) {
16505        if (userId == 0) {
16506            return true;
16507        }
16508        UserManagerService ums = getUserManagerLocked();
16509        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16510    }
16511
16512    int[] getUsersLocked() {
16513        UserManagerService ums = getUserManagerLocked();
16514        return ums != null ? ums.getUserIds() : new int[] { 0 };
16515    }
16516
16517    UserManagerService getUserManagerLocked() {
16518        if (mUserManager == null) {
16519            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16520            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16521        }
16522        return mUserManager;
16523    }
16524
16525    private int applyUserId(int uid, int userId) {
16526        return UserHandle.getUid(userId, uid);
16527    }
16528
16529    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16530        if (info == null) return null;
16531        ApplicationInfo newInfo = new ApplicationInfo(info);
16532        newInfo.uid = applyUserId(info.uid, userId);
16533        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16534                + info.packageName;
16535        return newInfo;
16536    }
16537
16538    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16539        if (aInfo == null
16540                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16541            return aInfo;
16542        }
16543
16544        ActivityInfo info = new ActivityInfo(aInfo);
16545        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16546        return info;
16547    }
16548}
16549